Analysis walkthrough for the paper “Good-enough production: Selecting easier words instead of accurate ones.” (authors removed, 2020).

See WordChoice_codebook for information about individual columns.

First, load all data across Experiments 1-4.

all_data <- read.csv(here::here("processed_data","Words_final_preprocessed.csv"))

Experiment 1

#load data
d <- filter(all_data,version=="exp1")

Demographics

Overview over the demographics of participants in Experiment 1.

#demographics and by-subject accuracy for each block
subjDemographics <- d %>%
  select(subjCode,Gender,Age,NativeLang,SecondLangYN) %>%
  unique() %>%
  summarize(
    N=n(),
    gender_f=sum(Gender=="Female"),
    mean_age=round(mean(Age,na.rm=T),2),
    sd_age=round(sd(Age,na.rm=T),2),
    min_age=round(min(Age,na.rm=T),2),
    max_age=round(max(Age,na.rm=T),2),
    native_english=sum(NativeLang=="Yes"),
    language_besides_english=sum(SecondLangYN=="Yes"),
  )

kable(subjDemographics)
N gender_f mean_age sd_age min_age max_age native_english language_besides_english
39 25 18.85 0.84 18 21 38 9

Pair Learning Accuracy

Overall Accuracy

Overview of participants’ performance during the Training Phase in which word participants learn each of the 8 compass directions.

#generate summary of learning block numbers
subj_block_numbers <- d %>%
  filter(trialType=="pairLearn"|trialType=="name") %>%
  group_by(subjCode) %>%
  summarize(
    num_pairlearn_blocks=max(pairLearnBlockNum,na.rm=T),
    num_name_blocks=max(nameBlockNum,na.rm=T),
  )
#combine with main data frame (for later covariate analysis)
d <- d %>%
  left_join(subj_block_numbers)

#generate by-subject accuracy for each block (repeated training blocks are averaged together)
subjAcc <- d %>%
  group_by(subjCode,trialType) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode)),
    rt = mean(rt,na.rm=T)) %>%
  ungroup()

#Overall Accuracy Pair Learning
overallPairAcc <- subjAcc %>%
  filter(trialType=="pairLearn") %>%
  summarize(
    acc=mean(accuracy,na.rm=T),
    sd = sd(accuracy),
    num_trials_avg = mean(numTrials),
    num_trials_sd = sd(numTrials),
    num_blocks_avg = mean(numTrials/20),
    num_blocks_sd= sd(numTrials/20))
kable(overallPairAcc)
acc sd num_trials_avg num_trials_sd num_blocks_avg num_blocks_sd
0.9520604 0.0308001 91.79487 38.58496 4.589744 1.929248

Accuracy by Block

#pair learning over time
#summarize by block
subj_pair_accuracy_by_block <- d %>%
  filter(trialType=="pairLearn"&!is.na(pairLearnBlockNum)) %>%
  group_by(subjCode,pairLearnBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_pair_accuracy_by_block <- subj_pair_accuracy_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("pairLearnBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(pairLearnBlockNum=as.numeric(as.character(pairLearnBlockNum)))

#one plot each subject is a line
pair_accuracy_by_block_exp1 <- ggplot(overall_pair_accuracy_by_block,aes(pairLearnBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.8))+
  scale_x_continuous(breaks=1:20)+
  scale_y_continuous(breaks=seq(0.5,1,0.1))+
  coord_cartesian(ylim = c(0.45, 1.05))+
  geom_hline(yintercept=0.5,linetype="dashed")+
  annotate("text",x=2,y=0.55,label="chance")+
  xlab("Word Learning Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Word Recall by Block

subj_training_recall_by_block <- d %>%
  filter(trialType=="name"&!is.na(nameBlockNum)) %>%
  group_by(subjCode,nameBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_training_recall_by_block <- subj_training_recall_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("nameBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(nameBlockNum=as.numeric(as.character(nameBlockNum)))

#one plot each subject is a line
training_recall_by_block_exp1 <- ggplot(overall_training_recall_by_block,aes(nameBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.25))+
  scale_x_continuous(breaks=1:20)+
  xlab("Training - Word Recall Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Final word retention

Timed Retention Test

Participants’ performance during the Timed Retention test at the conclusion of the experiment.

Accuracy

#summarize subject accuracy by frequency
subjAccFreq <- d %>%
  group_by(subjCode,block,freq) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    rt = mean(rt,na.rm=T)) %>%
  ungroup()

testXAcc <-  summarySEwithin(data=subset(subjAccFreq,block=="test_x"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
testXAcc$lowerCI <-  testXAcc$accuracy - testXAcc$ci
testXAcc$upperCI <- testXAcc$accuracy + testXAcc$ci
testXAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 39 0.9166667 0.0251083 0.8658375 0.9674958
lf 39 0.8461538 0.0251083 0.7953247 0.8969830
#t-test
t.test(subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = 1.9858, df = 38, p-value = 0.05431
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.001370471  0.142396112
## sample estimates:
## mean of the differences 
##              0.07051282

Reaction Times

# reaction times
testXRT <-  summarySEwithin(subset(subjAccFreq,block=="test_x"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
testXRT$lowerCI <-  testXRT$rt - testXRT$ci
testXRT$upperCI <-  testXRT$rt + testXRT$ci
testXRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 39 2346.792 80.80811 2183.205 2510.38
lf 39 2628.082 80.80811 2464.495 2791.67
#t-test
t.test(subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = -2.4614, df = 38, p-value = 0.01849
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -512.63778  -49.94257
## sample estimates:
## mean of the differences 
##               -281.2902

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(testXAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
  #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  xlab("Accuracy")+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(testXRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="test_x"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

# save plot
ggsave(here::here("plots","exp1_testXCheck.jpg"), width=9, height=6)

Untimed Retention Test

Participants’ performance on the Untimed Retention test at the conclusion of the experiment.

Accuracy

# accuracy
nameCheckAcc <-  summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
nameCheckAcc$lowerCI <-  nameCheckAcc$accuracy - nameCheckAcc$ci
nameCheckAcc$upperCI <-  nameCheckAcc$accuracy + nameCheckAcc$ci
nameCheckAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 39 0.974359 0.0129881 0.9480659 1.000652
lf 39 0.974359 0.0129881 0.9480659 1.000652
#t-test
t.test(subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = 0, df = 38, p-value = 1
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.03718399  0.03718399
## sample estimates:
## mean of the differences 
##                       0

Reaction Times

# reaction times
nameCheckRT <-  summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
nameCheckRT$lowerCI <-  nameCheckRT$rt - nameCheckRT$ci
nameCheckRT$upperCI <-  nameCheckRT$rt + nameCheckRT$ci
nameCheckRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 39 2755.277 126.7777 2498.629 3011.925
lf 39 3080.391 126.7777 2823.743 3337.039
#t-test
t.test(subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = -1.8133, df = 38, p-value = 0.07768
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -688.06881   37.84174
## sample estimates:
## mean of the differences 
##               -325.1135

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(nameCheckAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(nameCheckRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="name_check"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp1_finalNameCheck.jpg"), width=9, height=6)

Frequency Effect on Word Choice

Main Model

In our main analysis, we considered participants’ likelihood of choosing the word for the nearest compass direction, dependent on whether that compass direction was a high- or a low-frequency word, while controlling for the distance from the nearest learned compass direction. We focused specifically on low-frequency/high-frequency trials, in which a compass direction was tested in between a low-frequency and a high-frequency trained direction.

As a conservative test, we retained only trials in which participants chose one of the two principal direction words within 45° of the stimulus direction (94.41% of all low-frequency/high-frequency trials).

#just trials with a left or right angle choice
#model
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2453.4   2514.6  -1216.7   2433.4     3348 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -8.9254  0.0982  0.2040  0.4370  2.2482 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.240227 0.49013             
##              hfTrial             1.211711 1.10078  -0.26      
##              angleDiffFromMatchC 0.001383 0.03719  -0.98  0.06
##  targetLabel (Intercept)         0.020018 0.14149             
## Number of obs: 3358, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.34236    0.12216  19.174  < 2e-16 ***
## hfTrial              0.70564    0.20946   3.369 0.000755 ***
## angleDiffFromMatchC -0.22760    0.01347 -16.892  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.145       
## anglDffFrMC -0.778  0.039
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          2.1029300  2.5817911
## hfTrial              0.2951182  1.1161689
## angleDiffFromMatchC -0.2540037 -0.2011891
#calculate shift in x-axis units (degrees of angle)
shift_x <- -(summary(m)$coefficients[1,1]+0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1]
#low 95% CI
shift_x_lower <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[8:10,][2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[8:10,][2,1])/summary(m)$coefficients[3,1]
#high 95% CI
shift_x_upper <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[8:10,][2,2])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[8:10,][2,2])/summary(m)$coefficients[3,1]

## Main model has a singular fit warning - since this fit does not appear to impact fit, we retained the more complex random effects structure.
## However, we also fit a simplified model with the random slope for (the less theoretically important predictor) angleDiffFromMatchC removed, to ensure that the results are similar across different random effects structures and to alleviate concerns about a the boundary fit.
## This model yields very similar results (uncomment model below to view)
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

This effect corresponded to an estimated 3.1° shift (95% CI = [1.3°, 4.9°]) in participants’ decision boundary for high-frequency words as compared to low-frequency words.

Robustness Checks

Controlling for final retention accuracy of labels on each trial

To ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we first re-fit the model while controlling for participants’ accuracy during the Untimed Retention Test for the two (nearby) compass directions involved in each trial.

#controlling for accuracy for nearby labels
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels +  
##     (1 + hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels |  
##         subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2461.2   2553.0  -1215.6   2431.2     3343 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -9.3204  0.0982  0.2044  0.4364  2.2383 
## 
## Random effects:
##  Groups      Name                      Variance Std.Dev. Corr             
##  subjCode    (Intercept)               0.210633 0.45895                   
##              hfTrial                   1.219664 1.10438  -0.83            
##              angleDiffFromMatchC       0.001256 0.03544   0.49  0.08      
##              finalAccuracyNearbyLabels 0.637278 0.79830  -0.81  0.35 -0.91
##  targetLabel (Intercept)               0.017727 0.13314                   
## Number of obs: 3358, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                           Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                1.97635    0.94416   2.093 0.036329 *  
## hfTrial                    0.71757    0.21023   3.413 0.000642 ***
## angleDiffFromMatchC       -0.22721    0.01337 -16.997  < 2e-16 ***
## finalAccuracyNearbyLabels  0.36827    0.95035   0.388 0.698380    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.054              
## anglDffFrMC -0.054  0.047       
## fnlAccrcyNL -0.991  0.038 -0.046
## optimizer (bobyqa) convergence code: 1 (bobyqa -- maximum number of function evaluations exceeded)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[12:15,]
##                                2.5 %     97.5 %
## (Intercept)                0.1258202  3.8268763
## hfTrial                    0.3055331  1.1296137
## angleDiffFromMatchC       -0.2534079 -0.2010068
## finalAccuracyNearbyLabels -1.4943857  2.2309223
## maximal model yields a singular fit
## model with simpler random-effects structure (removing non-theoretically important random slope for angleDiffFromMatchC and finalAccuracyNearbyLabels) yields similar results for frequency effect without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Including only participants with perfect recall for all compass directions at the end of the experiment

To further ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we next re-fit the same model using a stricter inclusion criterion, including only participants who recalled all items correctly during the Untimed Retetion test.

final_accuracy <- d %>%
  filter(trialType=="finalName") %>%
  group_by(subjCode,trialType) %>%
  summarize(N=n(),accuracy=mean(isRight)) %>%
  ungroup()

#select only participants with perfect recall on the final test block
perfect_final_accuracy_subjects <- as.character(filter(final_accuracy,accuracy==1)$subjCode)

m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: 
## subset(d, listChoice == 1 & subjCode %in% perfect_final_accuracy_subjects)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2108.7   2168.6  -1044.3   2088.7     2946 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -8.7064  0.0947  0.1974  0.4321  2.1530 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.187489 0.43300             
##              hfTrial             0.785634 0.88636  -0.17      
##              angleDiffFromMatchC 0.001241 0.03523  -0.96 -0.11
##  targetLabel (Intercept)         0.074566 0.27307             
## Number of obs: 2956, groups:  subjCode, 34; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.46765    0.13898  17.755  < 2e-16 ***
## hfTrial              0.54033    0.19591   2.758  0.00582 ** 
## angleDiffFromMatchC -0.23838    0.01465 -16.268  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.085       
## anglDffFrMC -0.722 -0.001
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          2.1952530  2.7400423
## hfTrial              0.1563494  0.9243204
## angleDiffFromMatchC -0.2671023 -0.2096603
## maximal model yields a singular fit
## model with simpler random-effects structure (random slope for angleDiffFromMatchC removed) yields similar results without singular fit
# m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Controlling for compass direction character length

The words given to each of the compass directions varied in character length (and therefore perhaps in how easy they are to produce/ type). Beyond randomly assigning compass directions and counterbalancing their roles across participants, we also fit all models with by-item random effects to ensure that the effect of frequency generalizes across items. In the following model, we also explicitly control for character length to ensure that the effects hold even after accounting for character length of the nearest/ target compass direction.

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial+angleDiffFromMatchC+nearestLabel_length|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + nearestLabel_length +  
##     (1 + hfTrial + angleDiffFromMatchC + nearestLabel_length |  
##         subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2444.1   2535.9  -1207.1   2414.1     3343 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -8.0225  0.0931  0.2010  0.4242  2.3324 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev.  Corr             
##  subjCode    (Intercept)         2.899e+00 1.703e+00                  
##              hfTrial             1.359e+00 1.166e+00 -0.04            
##              angleDiffFromMatchC 1.458e-03 3.819e-02  0.22  0.00      
##              nearestLabel_length 1.869e-01 4.323e-01 -0.96 -0.03 -0.46
##  targetLabel (Intercept)         8.176e-09 9.042e-05                  
## Number of obs: 3358, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.57496    0.39227   6.564 5.23e-11 ***
## hfTrial              0.68557    0.21902   3.130  0.00175 ** 
## angleDiffFromMatchC -0.23066    0.01371 -16.829  < 2e-16 ***
## nearestLabel_length -0.04607    0.09452  -0.487  0.62595    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.040              
## anglDffFrMC -0.096  0.021       
## nrstLbl_lng -0.955 -0.005 -0.144
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##        2.5 % 97.5 %
## .sig08    NA     NA
## .sig09    NA     NA
## .sig10    NA     NA
## maximal model yields a singular fit
## model with simpler random-effects structure (random slopes for angleDiffFromMatchC and nearestLabel_length removed) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Controlling for number of training blocks

Since participants were required to produce all 8 compass directions perfectly during a Word Recall block in order to advance to the Treasure Hunt Phase (otherwise returning to the Word Learning Phase for further training), participants varied in the duration of their training. The extent to which participants were trained on the compass directions may influence the degree to which participants exhibited an effect of frequency on lexical selection. In the main logistic mixed-effects analyses demonstrating the effect of word frequency on lexical selection, we also fit a model controlling for differences in training duration by including the number of training blocks as a fixed effect.

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+num_pairlearn_blocks+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + num_pairlearn_blocks +  
##     (1 + hfTrial + angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2455.4   2522.7  -1216.7   2433.4     3347 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -8.9335  0.0982  0.2041  0.4372  2.2454 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.239875 0.48977             
##              hfTrial             1.212121 1.10096  -0.26      
##              angleDiffFromMatchC 0.001383 0.03718  -0.98  0.06
##  targetLabel (Intercept)         0.019839 0.14085             
## Number of obs: 3358, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                       Estimate Std. Error z value Pr(>|z|)    
## (Intercept)           2.356778   0.202841  11.619  < 2e-16 ***
## hfTrial               0.705767   0.209484   3.369 0.000754 ***
## angleDiffFromMatchC  -0.227600   0.013474 -16.892  < 2e-16 ***
## num_pairlearn_blocks -0.003137   0.035225  -0.089 0.929045    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.080              
## anglDffFrMC -0.471  0.040       
## nm_prlrn_bl -0.799 -0.008  0.004
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:11,]
##                            2.5 %      97.5 %
## (Intercept)           1.95921785  2.75433905
## hfTrial               0.29518598  1.11634837
## angleDiffFromMatchC  -0.25400799 -0.20119249
## num_pairlearn_blocks -0.07217659  0.06590322
## maximal model yields a singular fit
## model with simpler random-effects structure (random slope for angleDiffFromMatchC removed) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+num_pairlearn_blocks+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Checking for an interaction with distance

We also investigated whether distance interacted with frequency condition in predicting lexical selection. We find no evidence of an interaction between frequency and distance.

#full interaction model
#does not converge (boundary fit)
#m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial*angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
#simplified random effects structure preserving critical interaction random effect (qualitatively similar results to more complex models)
m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial:angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial * angleDiffFromMatchC + (1 + hfTrial:angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2477.5   2526.5  -1230.8   2461.5     3350 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -11.2560   0.0964   0.2240   0.4624   2.6402 
## 
## Random effects:
##  Groups      Name                        Variance Std.Dev. Corr 
##  subjCode    (Intercept)                 0.09213  0.3035        
##              hfTrial:angleDiffFromMatchC 0.01640  0.1280   -0.67
##  targetLabel (Intercept)                 0.02173  0.1474        
## Number of obs: 3358, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                             Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                  2.21327    0.09930  22.288  < 2e-16 ***
## hfTrial                      0.84854    0.15822   5.363 8.19e-08 ***
## angleDiffFromMatchC         -0.21592    0.01152 -18.735  < 2e-16 ***
## hfTrial:angleDiffFromMatchC -0.02118    0.03049  -0.694    0.487    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.093              
## anglDffFrMC -0.597  0.140       
## hfTrl:nDFMC -0.132 -0.535 -0.125

Reaction Time Analysis

Descriptives

We investigated participants’ speed in responding on trials in which they chose the nearest word (thereby maximizing message alignment - analogous to RT on “correct” trials).

# splitting reaction time by word frequency on trials during the Treasure Hunt Phase
summarized_rt <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency"))%>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt)
hfTrial N rt se lower_ci upper_ci
low-frequency 831 2663.290 43.89452 2577.133 2749.448
high-frequency 1920 2208.123 24.63067 2159.817 2256.429
summarized_rt_block <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("block","hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency")) %>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt_block)
block hfTrial N rt se lower_ci upper_ci
test_a low-frequency 298 2697.804 60.73265 2578.283 2817.325
test_a high-frequency 1244 2171.240 24.96053 2122.271 2220.210
test_b low-frequency 533 2643.994 44.40167 2556.770 2731.218
test_b high-frequency 676 2275.995 33.75532 2209.717 2342.273

Linear mixed-effects model

We fit a linear mixed-effect model predicting participants’ reaction times from Word Frequency (centered; High = -0.5 vs. Low = -0.5) and Distance from Nearest Principal Direction with the same random effects structure as above.

#RT effect on trials in which nearest word is chosen
m=lmer(rt~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: 
## rt ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial + angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 44593.7
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.5725 -0.6756 -0.2324  0.4728  6.2020 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev. Corr       
##  subjCode    (Intercept)         103153.79 321.176             
##              hfTrial              93233.81 305.342  -0.68      
##              angleDiffFromMatchC     20.38   4.514   0.12  0.29
##  targetLabel (Intercept)          24843.59 157.618             
##  Residual                        611630.85 782.068             
## Number of obs: 2751, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error t value
## (Intercept)         2455.289     65.679   37.38
## hfTrial             -405.370     61.330   -6.61
## angleDiffFromMatchC   10.071      2.665    3.78
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.483       
## anglDffFrMC  0.017  0.182
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                            F Df Df.res    Pr(>F)    
## (Intercept)         1396.774  1 47.493 < 2.2e-16 ***
## hfTrial               43.418  1 40.686 6.508e-08 ***
## angleDiffFromMatchC   14.193  1 36.902 0.0005763 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
confint(m,method="Wald")
##                           2.5 %     97.5 %
## .sig01                       NA         NA
## .sig02                       NA         NA
## .sig03                       NA         NA
## .sig04                       NA         NA
## .sig05                       NA         NA
## .sig06                       NA         NA
## .sig07                       NA         NA
## .sigma                       NA         NA
## (Intercept)         2326.560214 2584.01705
## hfTrial             -525.574789 -285.16436
## angleDiffFromMatchC    4.848783   15.29387
#no interaction with block
#include highest order interaction terms as random slopes
m=lmer(rt~(hfTrial+angleDiffFromMatchC)*blockC+(1+hfTrial:blockC+angleDiffFromMatchC:blockC|subjCode)+(1|targetLabel),data=subset(d,matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: rt ~ (hfTrial + angleDiffFromMatchC) * blockC + (1 + hfTrial:blockC +  
##     angleDiffFromMatchC:blockC | subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 44581.1
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.3139 -0.6736 -0.2381  0.4750  6.0297 
## 
## Random effects:
##  Groups      Name                       Variance Std.Dev. Corr       
##  subjCode    (Intercept)                127481   357.04              
##              hfTrial:blockC              50071   223.76    0.96      
##              blockC:angleDiffFromMatchC   1268    35.61   -0.74 -0.53
##  targetLabel (Intercept)                 27225   165.00              
##  Residual                               621439   788.31              
## Number of obs: 2751, groups:  subjCode, 39; targetLabel, 18
## 
## Fixed effects:
##                            Estimate Std. Error t value
## (Intercept)                2480.092     75.690  32.766
## hfTrial                    -410.046     37.331 -10.984
## angleDiffFromMatchC          19.388      4.838   4.007
## blockC                     -166.527     60.974  -2.731
## hfTrial:blockC              145.642     77.728   1.874
## angleDiffFromMatchC:blockC   -8.396     11.276  -0.745
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC blockC hfTr:C
## hfTrial     -0.074                            
## anglDffFrMC -0.064  0.003                     
## blockC       0.057  0.150 -0.824              
## hfTrl:blckC  0.394 -0.085 -0.020 -0.180       
## anglDfFMC:C -0.569 -0.016  0.104 -0.132 -0.124
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                                    F Df  Df.res    Pr(>F)    
## (Intercept)                1072.3726  1   51.04 < 2.2e-16 ***
## hfTrial                     119.1075  1 2460.66 < 2.2e-16 ***
## angleDiffFromMatchC          15.9340  1 2690.76 6.734e-05 ***
## blockC                        7.4101  1 2687.40  0.006528 ** 
## hfTrial:blockC                3.4931  1   48.34  0.067691 .  
## angleDiffFromMatchC:blockC    0.5512  1   38.75  0.462302    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Plot

Plot the effect of training frequency on word/ compass direction choice.

#refit model without centering angle for simpler plotting (coefficients essentially equivalent)
m <- glmer(matchChoice~hfTrial+angleDiffFromMatch+(1+hfTrial+angleDiffFromMatch|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))

pX <- expand.grid(angleDiffFromMatch=seq(0,22.5,by=0.1),hfTrial=c(-0.5,0.5))

predictions <- predictSE(m,pX,re.form=NA, type="response")
pX$fit <- predictions$fit
pX$se.fit <- predictions$se.fit

### Three different plotting designs - same effect ###

# Plot 1

q <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,matchChoice,color=as.character(hfTrial)))+
  geom_jitter(width=0.5,height=0.03,alpha=0.2)+
  #geom_violinh(aes(y=as.factor(matchChoice),fill=as.character(hfTrial)),scale="count",width=0.3,alpha=0.3,color=NA)+
  #geom_violinhalf(aes(y=as.factor(matchChoice),fill=as.character(hfTrial)),scale="count",width=0.3,alpha=0.3,color=NA,orientation="y")+
  geom_smooth(data=pX,aes(y=fit,ymax=fit+se.fit,ymin=fit-se.fit,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))#+
  #ylim(-0.05,1.05)
ggsave(here::here("plots","exp1_frequencyEffect_old.jpg"), width=9, height=6)

#Plot 2

p_freq1 <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, alpha=0.3,shape=19,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 0.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
p_freq1

ggsave(here::here("plots","exp1_frequencyEffect.jpg"), width=9, height=6)

# Plot 3

#alternate
p <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, shape=19,alpha=0.2,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 1.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.75,alpha=0.4, color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.75,alpha=0.4,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
ggsave(here::here("plots","exp1_frequencyEffect_alternate.jpg"), width=9, height=6)

Experiment 2

#load data
d <- filter(all_data, version=="exp2")

Demographics

Overview over the demographics of participants in Experiment 2.

#demographics 
subjDemographics <- d %>%
  select(subjCode,Gender,Age,NativeLang,SecondLangYN) %>%
  unique() %>%
  summarize(
    N=n(),
    gender_f=sum(Gender=="Female"),
    mean_age=round(mean(Age,na.rm=T),2),
    sd_age=round(sd(Age,na.rm=T),2),
    min_age=round(min(Age,na.rm=T),2),
    max_age=round(max(Age,na.rm=T),2),
    native_english=sum(NativeLang=="Yes"),
    language_besides_english=sum(SecondLangYN=="Yes"),
  )

kable(subjDemographics)
N gender_f mean_age sd_age min_age max_age native_english language_besides_english
44 26 18.45 0.87 18 23 43 5

Pair Learning Accuracy

Overall Pair Learning Accuracy

Overview of participants’ performance during the Training Phase in which word participants learn each of the 8 compass directions.

#generate summary of learning block numbers
subj_block_numbers <- d %>%
  filter(trialType=="pairLearn"|trialType=="name") %>%
  group_by(subjCode) %>%
  summarize(
    num_pairlearn_blocks=max(pairLearnBlockNum,na.rm=T),
    num_name_blocks=max(nameBlockNum,na.rm=T),
  )
#combine with main data frame (for later covariate analysis)
d <- d %>%
  left_join(subj_block_numbers)

#generate by-subject accuracy for each block (repeated training blocks are averaged together)
subjAcc <- d %>%
  group_by(subjCode,trialType) %>%
  summarize(accuracy=mean(isRight,na.rm=T),
              numTrials=sum(!is.na(subjCode)),
              rt = mean(rt,na.rm=T)) %>%
  ungroup()

#Overall Accuracy Pair Learning
overallPairAcc <- subjAcc %>%
  filter(trialType=="pairLearn") %>%
  summarize(
    acc=mean(accuracy,na.rm=T),
    sd = sd(accuracy),
    num_trials_avg = mean(numTrials),
    num_trials_sd = sd(numTrials),
    num_blocks_avg = mean(numTrials/20),
    num_blocks_sd= sd(numTrials/20))
kable(overallPairAcc)
acc sd num_trials_avg num_trials_sd num_blocks_avg num_blocks_sd
0.958008 0.0324513 87.27273 52.48981 4.363636 2.62449

Accuracy by Block

#pair learning over time
#summarize by block
subj_pair_accuracy_by_block <- d %>%
  filter(trialType=="pairLearn"&!is.na(pairLearnBlockNum)) %>%
  group_by(subjCode,pairLearnBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_pair_accuracy_by_block <- subj_pair_accuracy_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("pairLearnBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(pairLearnBlockNum=as.numeric(as.character(pairLearnBlockNum)))

#one plot each subject is a line
pair_accuracy_by_block_exp2 <- ggplot(overall_pair_accuracy_by_block,aes(pairLearnBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.8))+
  scale_x_continuous(breaks=1:20)+
  scale_y_continuous(breaks=seq(0.5,1,0.1))+
  coord_cartesian(ylim = c(0.45, 1.05))+
  geom_hline(yintercept=0.5,linetype="dashed")+
  annotate("text",x=2,y=0.55,label="chance")+
  xlab("Word Learning Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Word Recall by Block

subj_training_recall_by_block <- d %>%
  filter(trialType=="name"&!is.na(nameBlockNum)) %>%
  group_by(subjCode,nameBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_training_recall_by_block <- subj_training_recall_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("nameBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(nameBlockNum=as.numeric(as.character(nameBlockNum)))

#one plot each subject is a line
training_recall_by_block_exp2 <- ggplot(overall_training_recall_by_block,aes(nameBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.25))+
  scale_x_continuous(breaks=1:20)+
  xlab("Training - Word Recall Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Final word retention

Timed Retention Test

Participants’ performance during the Timed Retention test at the conclusion of the experiment.

Accuracy

#summarize subject accuracy by frequency
subjAccFreq <- d %>%
  group_by(subjCode,block,freq) %>%
  summarize(accuracy=mean(isRight,na.rm=T),
                  rt = mean(rt,na.rm=T)) %>%
  ungroup()

testXAcc <- summarySEwithin(data=subset(subjAccFreq,block=="test_x"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
testXAcc$lowerCI <- testXAcc$accuracy - testXAcc$ci
testXAcc$upperCI <- testXAcc$accuracy + testXAcc$ci
testXAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 44 0.9375000 0.0244461 0.8881997 0.9868003
lf 44 0.8465909 0.0244461 0.7972906 0.8958912
#t-test
t.test(subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = 2.6296, df = 43, p-value = 0.01181
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  0.02118799 0.16063019
## sample estimates:
## mean of the differences 
##              0.09090909

Reaction Times

testXRT <- summarySEwithin(subset(subjAccFreq,block=="test_x"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
testXRT$lowerCI <- testXRT$rt - testXRT$ci
testXRT$upperCI <- testXRT$rt + testXRT$ci
testXRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 44 2366.493 63.98186 2237.461 2495.525
lf 44 2540.931 63.98186 2411.900 2669.963
#t-test
t.test(subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = -1.9278, df = 43, p-value = 0.0605
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -356.916710    8.040105
## sample estimates:
## mean of the differences 
##               -174.4383

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(testXAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(testXRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="test_x"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp2_testXCheck.jpg"),width=9, height=6)

Untimed Retention Test

Participants’ performance on the Untimed Retention test at the conclusion of the experiment.

Accuracy

nameCheckAcc <- summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
nameCheckAcc$lowerCI <- nameCheckAcc$accuracy - nameCheckAcc$ci
nameCheckAcc$upperCI <- nameCheckAcc$accuracy + nameCheckAcc$ci
nameCheckAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 44 0.9886364 0.0127786 0.9628659 1.0144068
lf 44 0.9488636 0.0127786 0.9230932 0.9746341
#t-test
t.test(subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = 2.2008, df = 43, p-value = 0.03317
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  0.003327778 0.076217677
## sample estimates:
## mean of the differences 
##              0.03977273

Reaction Times

nameCheckRT <- summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
nameCheckRT$lowerCI <- nameCheckRT$rt - nameCheckRT$ci
nameCheckRT$upperCI <- nameCheckRT$rt + nameCheckRT$ci
nameCheckRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 44 2683.890 120.6361 2440.604 2927.175
lf 44 2982.349 120.6361 2739.063 3225.635
#t-test
t.test(subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = -1.7494, df = 43, p-value = 0.08735
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -642.5172   45.5989
## sample estimates:
## mean of the differences 
##               -298.4592

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(nameCheckAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(nameCheckRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="name_check"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp2_finalNameCheck.jpg"), width=9, height=6)

Frequency Effect on Word Choice

Main Model

As in Experiment 1, we considered participants’ likelihood of choosing the word for the nearest compass direction, dependent on whether that compass direction was a high- or a low-frequency word, while controlling for the distance from the nearest learned compass direction. We focused specifically on low-frequency/high-frequency trials, in which a compass direction was tested in between a low-frequency and a high-frequency trained direction.

As a conservative test, we retained only trials in which participants chose one of the two principal direction words within 45° of the stimulus direction (93.78% of all low-frequency/high-frequency trials).

#just trials with a left or right angle choice
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1961.2   2019.4   -970.6   1941.2     2477 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.5877  0.0733  0.2173  0.4400  3.2164 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.19173  0.43787             
##              hfTrial             3.47024  1.86286   0.16      
##              angleDiffFromMatchC 0.00165  0.04062  -1.00 -0.16
##  targetLabel (Intercept)         0.08061  0.28392             
## Number of obs: 2487, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          1.98412    0.13135  15.105  < 2e-16 ***
## hfTrial              1.35682    0.31086   4.365 1.27e-05 ***
## angleDiffFromMatchC -0.18780    0.01394 -13.476  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial      0.129       
## anglDffFrMC -0.637 -0.075
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          1.7266685  2.2415632
## hfTrial              0.7475493  1.9660902
## angleDiffFromMatchC -0.2151160 -0.1604871
#calculate shift in x-axis units (degrees of angle)
shift_x <- -(summary(m)$coefficients[1,1]+0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1]
#low 95% CI
shift_x_lower <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[8:10,][2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[8:10,][2,1])/summary(m)$coefficients[3,1]
#high 95% CI
shift_x_upper <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[8:10,][2,2])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[8:10,][2,2])/summary(m)$coefficients[3,1]

## maximal model yields a singular fit
## model with simpler random-effects structure (random slope for angleDiffFromMatchC removed) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

This effect corresponded to an estimated 7.22° shift (95% CI = [3.98°, 10.47°]) in participants’ decision boundary for high-frequency words as compared to low-frequency words.

Robustness Checks

Controlling for final retention accuracy of labels on each trial

To ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we first re-fit the model while controlling for participants’ accuracy during the Untimed Retention Test for the two (nearby) compass directions involved in each trial.

#controlling for accuracy for nearby labels
m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels +  
##     (1 + hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels |  
##         subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1962.7   2050.0   -966.4   1932.7     2472 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.8718  0.0705  0.2146  0.4369  3.0736 
## 
## Random effects:
##  Groups      Name                      Variance Std.Dev. Corr             
##  subjCode    (Intercept)               1.031544 1.01565                   
##              hfTrial                   3.454947 1.85875  -0.07            
##              angleDiffFromMatchC       0.001705 0.04129  -0.05 -0.22      
##              finalAccuracyNearbyLabels 1.349101 1.16151  -0.92  0.15 -0.36
##  targetLabel (Intercept)               0.078372 0.27995                   
## Number of obs: 2487, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                           Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                0.57991    0.74863   0.775   0.4386    
## hfTrial                    1.35958    0.31051   4.379 1.19e-05 ***
## angleDiffFromMatchC       -0.19049    0.01415 -13.467  < 2e-16 ***
## finalAccuracyNearbyLabels  1.46634    0.75835   1.934   0.0532 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial      0.001              
## anglDffFrMC -0.035 -0.098       
## fnlAccrcyNL -0.984  0.029 -0.082
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[12:15,]
##                                 2.5 %     97.5 %
## (Intercept)               -0.88737414  2.0472006
## hfTrial                    0.75098907  1.9681708
## angleDiffFromMatchC       -0.21821691 -0.1627695
## finalAccuracyNearbyLabels -0.01999638  2.9526832
## maximal model yields a singular fit
## model with simpler random-effects structure (removing non-theoretically important random slope for angleDiffFromMatchC) yields similar results for frequency effect without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial+finalAccuracyNearbyLabels|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Including only participants with perfect recall for all compass directions at the end of the experiment

To further ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we next re-fit the same model using a stricter inclusion criterion, including only participants who recalled all items correctly during the Untimed Retetion test.

final_accuracy <- d %>%
  filter(trialType=="finalName") %>%
  group_by(subjCode,trialType) %>%
  summarize(N=n(),accuracy=mean(isRight)) %>%
  ungroup()

#select only participants with perfect recall on the final test block
perfect_final_accuracy_subjects <- as.character(filter(final_accuracy,accuracy==1)$subjCode)

m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: 
## subset(d, listChoice == 1 & subjCode %in% perfect_final_accuracy_subjects)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1611.8   1667.8   -795.9   1591.8     1990 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.9569  0.0908  0.2327  0.4591  2.0653 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.18320  0.42802             
##              hfTrial             1.85778  1.36301   0.26      
##              angleDiffFromMatchC 0.00146  0.03822  -0.97 -0.01
##  targetLabel (Intercept)         0.05249  0.22910             
## Number of obs: 2000, groups:  subjCode, 35; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          1.99128    0.13653  14.585  < 2e-16 ***
## hfTrial              1.19493    0.27050   4.417 9.99e-06 ***
## angleDiffFromMatchC -0.18848    0.01542 -12.227  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial      0.182       
## anglDffFrMC -0.686 -0.005
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          1.7236917  2.2588695
## hfTrial              0.6647553  1.7251108
## angleDiffFromMatchC -0.2186979 -0.1582714
## maximal model yields a singular fit
## model with simpler random-effects structure (random slope for angleDiffFromMatchC removed) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1& subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Controlling for compass direction character length

The words given to each of the compass directions varied in character length (and therefore perhaps in how easy they are to produce/ type). Beyond randomly assigning compass directions and counterbalancing their roles across participants, we also fit all models with by-item random effects to ensure that the effect of frequency generalizes across items. In the following model, we also explicitly control for character length to ensure that the effects hold even after accounting for character length of the nearest/ target compass direction.

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial+angleDiffFromMatchC+nearestLabel_length|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + nearestLabel_length +  
##     (1 + hfTrial + angleDiffFromMatchC + nearestLabel_length |  
##         subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1941.9   2029.2   -955.9   1911.9     2472 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -6.2233  0.0650  0.1983  0.4176  2.7406 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr             
##  subjCode    (Intercept)         7.669988 2.76947                   
##              hfTrial             4.252725 2.06221  -0.06            
##              angleDiffFromMatchC 0.002073 0.04553  -0.40 -0.03      
##              nearestLabel_length 0.338741 0.58201  -0.99  0.09  0.27
##  targetLabel (Intercept)         0.065591 0.25611                   
## Number of obs: 2487, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          1.35321    0.61768   2.191   0.0285 *  
## hfTrial              1.38450    0.34421   4.022 5.77e-05 ***
## angleDiffFromMatchC -0.19457    0.01496 -13.005  < 2e-16 ***
## nearestLabel_length  0.16549    0.13645   1.213   0.2252    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.027              
## anglDffFrMC -0.213 -0.033       
## nrstLbl_lng -0.975  0.060  0.069
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[12:15,]
##                          2.5 %     97.5 %
## (Intercept)          0.1425822  2.5638352
## hfTrial              0.7098552  2.0591404
## angleDiffFromMatchC -0.2238888 -0.1652451
## nearestLabel_length -0.1019418  0.4329154
## maximal model yields a singular fit
## model with simpler random-effects structure (random slope for angleDiffFromMatchC removed) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial+nearestLabel_length|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Controlling for number of training blocks

Since participants were required to produce all 8 compass directions perfectly during a Word Recall block in order to advance to the Treasure Hunt Phase (otherwise returning to the Word Learning Phase for further training), participants varied in the duration of their training. The extent to which participants were trained on the compass directions may influence the degree to which participants exhibited an effect of frequency on lexical selection. In the main logistic mixed-effects analyses demonstrating the effect of word frequency on lexical selection, we also fit a model controlling for differences in training duration by including the number of training blocks as a fixed effect.

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+num_pairlearn_blocks+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + num_pairlearn_blocks +  
##     (1 + hfTrial + angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1961.2   2025.2   -969.6   1939.2     2476 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -5.7185  0.0745  0.2188  0.4388  3.2439 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.164230 0.4053              
##              hfTrial             3.397112 1.8431    0.21      
##              angleDiffFromMatchC 0.001529 0.0391   -1.00 -0.18
##  targetLabel (Intercept)         0.074289 0.2726              
## Number of obs: 2487, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                      Estimate Std. Error z value Pr(>|z|)    
## (Intercept)           2.14303    0.16957  12.638  < 2e-16 ***
## hfTrial               1.35767    0.30802   4.408 1.04e-05 ***
## angleDiffFromMatchC  -0.18700    0.01385 -13.505  < 2e-16 ***
## num_pairlearn_blocks -0.03944    0.02708  -1.456    0.145    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial      0.118              
## anglDffFrMC -0.464 -0.078       
## nm_prlrn_bl -0.660 -0.009 -0.022
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:11,]
##                            2.5 %      97.5 %
## (Intercept)           1.81068581  2.47537104
## hfTrial               0.75395528  1.96137685
## angleDiffFromMatchC  -0.21413470 -0.15985738
## num_pairlearn_blocks -0.09252334  0.01364381
## maximal model yields a singular fit
## model with simpler random-effects structure yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+num_pairlearn_blocks+(1|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Checking for an interaction with distance

We also investigated whether distance interacted with frequency condition in predicting lexical selection. We find no evidence of an interaction between frequency and distance.

#full interaction model
#does not converge (boundary fit)
# m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial*angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)
#simplified random effects structure preserving critical interaction random effect (qualitatively similar results to more complex models)
m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial+hfTrial:angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial * angleDiffFromMatchC + (1 + hfTrial +  
##     hfTrial:angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1967.5   2031.5   -972.7   1945.5     2476 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -6.8213  0.0848  0.2182  0.4422  3.2858 
## 
## Random effects:
##  Groups      Name                        Variance Std.Dev. Corr       
##  subjCode    (Intercept)                 0.045087 0.21234             
##              hfTrial                     3.344382 1.82877   0.41      
##              hfTrial:angleDiffFromMatchC 0.002523 0.05023  -0.59  0.23
##  targetLabel (Intercept)                 0.079293 0.28159             
## Number of obs: 2487, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                  1.911227   0.118181  16.172  < 2e-16 ***
## hfTrial                      1.392498   0.324233   4.295 1.75e-05 ***
## angleDiffFromMatchC         -0.177539   0.012916 -13.746  < 2e-16 ***
## hfTrial:angleDiffFromMatchC -0.009004   0.025030  -0.360    0.719    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial      0.129              
## anglDffFrMC -0.523  0.033       
## hfTrl:nDFMC -0.002 -0.253 -0.071

Reaction Time Analysis

Descriptives

We investigated participants’ speed in responding on trials in which they chose the nearest word (thereby maximizing message alignment - analogous to RT on “correct” trials).

# splitting reaction time by word frequency on trials during the Treasure Hunt Phase
summarized_rt <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency"))%>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt)
hfTrial N rt se lower_ci upper_ci
low-frequency 566 2501.262 52.85624 2397.443 2605.081
high-frequency 1380 2277.813 29.61640 2219.715 2335.911
summarized_rt_block <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("block","hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency")) %>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt_block)
block hfTrial N rt se lower_ci upper_ci
ambig low-frequency 379 2503.217 49.55543 2405.778 2600.655
ambig high-frequency 468 2266.878 40.43001 2187.431 2346.325
clear low-frequency 57 2649.258 177.80921 2293.063 3005.452
clear high-frequency 317 2369.977 48.91000 2273.747 2466.208
clear2 low-frequency 130 2430.672 69.56201 2293.042 2568.303
clear2 high-frequency 595 2237.312 33.62974 2171.265 2303.360

Linear mixed-effects model

We fit a linear mixed-effect model predicting participants’ reaction times from Word Frequency (centered; High = -0.5 vs. Low = -0.5) and Distance from Nearest Principal Direction with the same random effects structure as above.

#RT effect on trials in which nearest word is chosen
#maximal model does not converge, so remove least important
m=lmer(rt~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: 
## rt ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial + angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 31602.7
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.2649 -0.6685 -0.2096  0.4536  7.0173 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev. Corr       
##  subjCode    (Intercept)          89443.05 299.070             
##              hfTrial             113307.75 336.612  -0.23      
##              angleDiffFromMatchC     26.23   5.122  -0.35  0.99
##  targetLabel (Intercept)          50706.75 225.182             
##  Residual                        617467.62 785.791             
## Number of obs: 1946, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error t value
## (Intercept)         2393.714     73.151  32.723
## hfTrial             -220.322     66.130  -3.332
## angleDiffFromMatchC    9.134      3.172   2.879
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.192       
## anglDffFrMC -0.060  0.329
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                             F Df Df.res    Pr(>F)    
## (Intercept)         1068.3974  1 36.592 < 2.2e-16 ***
## hfTrial               11.0349  1 40.715  0.001896 ** 
## angleDiffFromMatchC    8.1889  1 40.788  0.006621 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
confint(m,method="Wald")
##                           2.5 %    97.5 %
## .sig01                       NA        NA
## .sig02                       NA        NA
## .sig03                       NA        NA
## .sig04                       NA        NA
## .sig05                       NA        NA
## .sig06                       NA        NA
## .sig07                       NA        NA
## .sigma                       NA        NA
## (Intercept)         2250.340632 2537.0875
## hfTrial             -349.934974  -90.7097
## angleDiffFromMatchC    2.915708   15.3515
#no interaction with block
#include highest order interaction terms as random slopes
m=lmer(rt~(hfTrial+angleDiffFromMatchC)*blockC+(1+hfTrial:blockC+angleDiffFromMatchC:blockC|subjCode)+(1|targetLabel),data=subset(d,matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: rt ~ (hfTrial + angleDiffFromMatchC) * blockC + (1 + hfTrial:blockC +  
##     angleDiffFromMatchC:blockC | subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 31635.7
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -1.9934 -0.6857 -0.2335  0.4428  7.5736 
## 
## Random effects:
##  Groups      Name                       Variance Std.Dev. Corr       
##  subjCode    (Intercept)                     0     0.00              
##              hfTrial:blockC              15956   126.32     NaN      
##              blockC:angleDiffFromMatchC   6114    78.19     NaN -1.00
##  targetLabel (Intercept)                 43649   208.92              
##  Residual                               656276   810.11              
## Number of obs: 1946, groups:  subjCode, 44; targetLabel, 18
## 
## Fixed effects:
##                            Estimate Std. Error t value
## (Intercept)                2358.958     62.461  37.767
## hfTrial                    -243.789     43.779  -5.569
## angleDiffFromMatchC          27.023      5.854   4.616
## blockC                     -271.935     75.009  -3.625
## hfTrial:blockC              -39.313     88.859  -0.442
## angleDiffFromMatchC:blockC    7.007     16.727   0.419
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC blockC hfTr:C
## hfTrial     -0.141                            
## anglDffFrMC -0.060 -0.044                     
## blockC       0.035  0.224 -0.815              
## hfTrl:blckC  0.126 -0.126 -0.018 -0.226       
## anglDfFMC:C -0.347 -0.010  0.060 -0.070 -0.179
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                                    F Df  Df.res    Pr(>F)    
## (Intercept)                1420.3903  1   28.89 < 2.2e-16 ***
## hfTrial                      30.6175  1 1847.98 3.592e-08 ***
## angleDiffFromMatchC          21.1203  1 1881.71 4.600e-06 ***
## blockC                       12.9806  1 1828.05 0.0003232 ***
## hfTrial:blockC                0.1940  1   59.54 0.6612048    
## angleDiffFromMatchC:blockC    0.1746  1   42.54 0.6781796    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Plot

Plot the effect of training frequency on word/ compass direction choice.

#refit model without centering angle for simpler plotting (coefficients roughly equivalent)
m <- glmer(matchChoice~hfTrial+angleDiffFromMatch+(1+hfTrial+angleDiffFromMatch|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))

pX <- expand.grid(angleDiffFromMatch=seq(0,22.5,by=0.1),hfTrial=c(-0.5,0.5))

predictions <- predictSE(m,pX,re.form=NA, type="response")
pX$fit <- predictions$fit
pX$se.fit <- predictions$se.fit

#### Three different plot options - same basic design ####

# Plot 1

q <- ggplot(subset(d, trialType=="test"),aes(angleDiffFromMatch,matchChoice,color=as.character(hfTrial)))+
  geom_jitter(width=0.5,height=0.03,alpha=0.2)+
  #geom_violinh(aes(y=matchChoice,group=hfTrial),scale="count",width=0.5)+
  geom_smooth(data=pX,aes(y=fit,ymax=fit+se.fit,ymin=fit-se.fit,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing nearest word")+
  scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
                     breaks=c(-0.5,0.5),
                     labels=c("Low-Frequency","High-Frequency"),direction=-1)+
  scale_fill_brewer(palette="Set1",name="Frequency of Nearest Word",
                     breaks=c(-0.5,0.5),
                     labels=c("Low-Frequency","High-Frequency"),direction=-1)+
  xlab("Distance from nearest word")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))+
  ylim(-0.05,1.05)
ggsave(here::here("plots","exp2_frequencyEffect_old.jpg"), width=9, height=6)

# Plot 2

p_freq2 <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, alpha=0.3,shape=19,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 0.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
p_freq2

ggsave(here::here("plots","exp2_frequencyEffect.jpg"), width=9, height=6)

# Plot 3

#alternate
p <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, shape=19,alpha=0.2,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 1.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.75,alpha=0.4, color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.75,alpha=0.4,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
ggsave(here::here("plots","exp2_frequencyEffect_alternate.jpg"), width=9, height=6)

Experiment 3

#load data
d <- filter(all_data,version=="exp3")

Demographics

Overview over the demographics of participants in Experiment 3.

#demographics
subjDemographics <- d %>%
  select(subjCode,Gender,Age,NativeLang,SecondLangYN) %>%
  unique() %>%
  summarize(
    N=n(),
    gender_f=sum(Gender=="Female"),
    mean_age=round(mean(Age,na.rm=T),2),
    sd_age=round(sd(Age,na.rm=T),2),
    min_age=round(min(Age,na.rm=T),2),
    max_age=round(max(Age,na.rm=T),2),
    native_english=sum(NativeLang=="Yes"),
    language_besides_english=sum(SecondLangYN=="Yes"),
  )

kable(subjDemographics)
N gender_f mean_age sd_age min_age max_age native_english language_besides_english
55 38 18.87 0.88 18 22 54 6

Pair Learning Accuracy

Overall Pair Learning Accuracy

Overview of participants’ performance during the Training Phase in which word participants learn each of the 8 compass directions.

#generate summary of learning block numbers
subj_block_numbers <- d %>%
  filter(trialType=="pairLearn"|trialType=="name") %>%
  group_by(subjCode) %>%
  summarize(
    num_pairlearn_blocks=max(pairLearnBlockNum,na.rm=T),
    num_name_blocks=max(nameBlockNum,na.rm=T),
  )
#combine with main data frame (for later covariate analysis)
d <- d %>%
  left_join(subj_block_numbers)

#generate by-subject accuracy for each block (repeated training blocks are averaged together)
subjAcc <- d %>%
  group_by(subjCode,trialType) %>%
  summarize(accuracy=mean(isRight,na.rm=T),
              numTrials=sum(!is.na(subjCode)),
              rt = mean(rt,na.rm=T)) %>%
  ungroup()

#Overall Accuracy Pair Learning
overallPairAcc <- subjAcc %>%
  filter(trialType=="pairLearn") %>%
  summarize(
    acc=mean(accuracy,na.rm=T),
    sd = sd(accuracy),
    num_trials_avg = mean(numTrials),
    num_trials_sd = sd(numTrials),
    num_blocks_avg = mean(numTrials/20),
    num_blocks_sd= sd(numTrials/20))
kable(overallPairAcc)
acc sd num_trials_avg num_trials_sd num_blocks_avg num_blocks_sd
0.9441321 0.0415011 92.72727 39.88198 4.636364 1.994099

Accuracy by Block

#pair learning over time
#summarize by block
subj_pair_accuracy_by_block <- d %>%
  filter(trialType=="pairLearn"&!is.na(pairLearnBlockNum)) %>%
  group_by(subjCode,pairLearnBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_pair_accuracy_by_block <- subj_pair_accuracy_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("pairLearnBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(pairLearnBlockNum=as.numeric(as.character(pairLearnBlockNum)))

#one plot each subject is a line
pair_accuracy_by_block_exp3 <- ggplot(overall_pair_accuracy_by_block,aes(pairLearnBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.8))+
  scale_x_continuous(breaks=1:20)+
  scale_y_continuous(breaks=seq(0.5,1,0.1))+
  coord_cartesian(ylim = c(0.45, 1.05))+
  geom_hline(yintercept=0.5,linetype="dashed")+
  annotate("text",x=2,y=0.55,label="chance")+
  xlab("Word Learning Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Word Recall by Block

subj_training_recall_by_block <- d %>%
  filter(trialType=="name"&!is.na(nameBlockNum)) %>%
  group_by(subjCode,nameBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_training_recall_by_block <- subj_training_recall_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("nameBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(nameBlockNum=as.numeric(as.character(nameBlockNum)))

#one plot each subject is a line
training_recall_by_block_exp3 <- ggplot(overall_training_recall_by_block,aes(nameBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.25))+
  scale_x_continuous(breaks=1:20)+
  xlab("Training - Word Recall Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Final word retention

Timed Retention Test

Participants’ performance during the Timed Retention test at the conclusion of the experiment.

Accuracy

#summarize subject accuracy by frequency
subjAccFreq <- d %>%
  group_by(subjCode,block,freq) %>%
  summarize(accuracy=mean(isRight,na.rm=T),
                  rt = mean(rt,na.rm=T)) %>%
  ungroup()

testXAcc <- summarySEwithin(data=subset(subjAccFreq,block=="test_x"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
testXAcc$lowerCI <- testXAcc$accuracy - testXAcc$ci
testXAcc$upperCI <- testXAcc$accuracy + testXAcc$ci
testXAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 55 0.9181818 0.0216495 0.8747771 0.9615865
lf 55 0.8954545 0.0216495 0.8520499 0.9388592
#t-test
t.test(subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = 0.74231, df = 54, p-value = 0.4611
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.03865624  0.08411078
## sample estimates:
## mean of the differences 
##              0.02272727

Reaction Times

testXRT <- summarySEwithin(subset(subjAccFreq,block=="test_x"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
testXRT$lowerCI <- testXRT$rt - testXRT$ci
testXRT$upperCI <- testXRT$rt + testXRT$ci
testXRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 55 2311.104 52.32621 2206.196 2416.011
lf 55 2447.317 52.32621 2342.410 2552.225
#t-test
t.test(subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = -1.8407, df = 54, p-value = 0.07116
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -284.57566   12.14825
## sample estimates:
## mean of the differences 
##               -136.2137

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(testXAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(testXRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="test_x"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp3_testXCheck.jpg"), width=9, height=6)

Untimed Retention Test

Participants’ performance on the Untimed Retention test at the conclusion of the experiment.

Accuracy

nameCheckAcc <- summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
nameCheckAcc$lowerCI <- nameCheckAcc$accuracy - nameCheckAcc$ci
nameCheckAcc$upperCI <- nameCheckAcc$accuracy + nameCheckAcc$ci
nameCheckAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 55 0.9772727 0.0135095 0.9501878 1.0043577
lf 55 0.9500000 0.0135095 0.9229151 0.9770849
#t-test
t.test(subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = 1.4275, df = 54, p-value = 0.1592
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -0.01103116  0.06557662
## sample estimates:
## mean of the differences 
##              0.02727273

Reaction Times

nameCheckRT <- summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
nameCheckRT$lowerCI <- nameCheckRT$rt - nameCheckRT$ci
nameCheckRT$upperCI <- nameCheckRT$rt + nameCheckRT$ci
nameCheckRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 55 2580.696 78.00042 2424.314 2737.077
lf 55 2603.112 78.00042 2446.731 2759.494
#t-test
t.test(subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = -0.20321, df = 54, p-value = 0.8397
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -243.5731  198.7403
## sample estimates:
## mean of the differences 
##               -22.41637

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(nameCheckAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(nameCheckRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="name_check"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp3_finalNameCheck.jpg"), width=9, height=6)

Frequency Effect on Word Choice

Main Model

As in Experiments 1 & 2, we considered participants’ likelihood of choosing the word for the nearest compass direction, dependent on whether that compass direction was a high- or a low-frequency word, while controlling for the distance from the nearest learned compass direction. We focused specifically on low-frequency/high-frequency trials, in which a compass direction was tested in between a low-frequency and a high-frequency trained direction.

As a conservative test, we retained only trials in which participants chose one of the two principal direction words within 45° of the stimulus direction (95.17% of all low-frequency/high-frequency trials).

#just trials with a left or right angle choice
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2244.4   2304.9  -1112.2   2224.4     3143 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -9.3833  0.0842  0.1958  0.3990  2.9865 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.194531 0.44106             
##              hfTrial             4.020349 2.00508   0.00      
##              angleDiffFromMatchC 0.001765 0.04201  -0.99  0.13
##  targetLabel (Intercept)         0.124657 0.35307             
## Number of obs: 3153, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.29960    0.14009  16.416   <2e-16 ***
## hfTrial              1.17394    0.30173   3.891    1e-04 ***
## angleDiffFromMatchC -0.19687    0.01387 -14.195   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial      0.060       
## anglDffFrMC -0.619  0.040
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          2.0250385  2.5741703
## hfTrial              0.5825591  1.7653226
## angleDiffFromMatchC -0.2240504 -0.1696861
#calculate shift in x-axis units (degrees of angle)
shift_x <- -(summary(m)$coefficients[1,1]+0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1]
#low 95% CI
shift_x_lower <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[8:10,][2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[8:10,][2,1])/summary(m)$coefficients[3,1]
#high 95% CI
shift_x_upper <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[8:10,][2,2])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[8:10,][2,2])/summary(m)$coefficients[3,1]

## maximal model yields a singular fit
## model with simpler random-effects structure (random slope for angleDiffFromMatchC removed) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

This effect corresponded to an estimated 5.96° shift (95% CI = [2.96°, 8.97°]) in participants’ decision boundary for high-frequency words as compared to low-frequency words.

Robustness Checks

Controlling for final retention accuracy of labels on each trial

To ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we first re-fit the model while controlling for participants’ accuracy during the Untimed Retention Test for the two (nearby) compass directions involved in each trial.

#controlling for accuracy for nearby labels
#maximal model does not converge (degenerate Hessian) and has implausible standard errors
# m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))

# refitting a simplified model with theoretically less important random slope removed (angleDiffFromMatchC)
m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial+finalAccuracyNearbyLabels|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels +  
##     (1 + hfTrial + finalAccuracyNearbyLabels | subjCode) + (1 |  
##     targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2227.5   2294.2  -1102.8   2205.5     3142 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -15.0671   0.0839   0.1980   0.3960   3.0173 
## 
## Random effects:
##  Groups      Name                      Variance Std.Dev. Corr       
##  subjCode    (Intercept)               2.9019   1.7035              
##              hfTrial                   3.9854   1.9963   -0.05      
##              finalAccuracyNearbyLabels 2.9531   1.7185   -1.00  0.08
##  targetLabel (Intercept)               0.1125   0.3353              
## Number of obs: 3153, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                           Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                0.52882    0.68369   0.773  0.43923    
## hfTrial                    1.20954    0.29876   4.048 5.15e-05 ***
## angleDiffFromMatchC       -0.19019    0.01146 -16.600  < 2e-16 ***
## finalAccuracyNearbyLabels  1.78809    0.68876   2.596  0.00943 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.030              
## anglDffFrMC -0.040  0.015       
## fnlAccrcyNL -0.985  0.050 -0.044
confint(m,method="Wald")[8:11,]
##                                2.5 %     97.5 %
## (Intercept)               -0.8111790  1.8688253
## hfTrial                    0.6239735  1.7950967
## angleDiffFromMatchC       -0.2126440 -0.1677335
## finalAccuracyNearbyLabels  0.4381496  3.1380337

Including only participants with perfect recall for all compass directions at the end of the experiment

To further ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we next re-fit the same model using a stricter inclusion criterion, including only participants who recalled all items correctly during the Untimed Retetion test.

final_accuracy <- d %>%
  filter(trialType=="finalName") %>%
  group_by(subjCode,trialType) %>%
  summarize(N=n(),accuracy=mean(isRight)) %>%
  ungroup()

#select only participants with perfect recall on the final test block
perfect_final_accuracy_subjects <- as.character(filter(final_accuracy,accuracy==1)$subjCode)

m=glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: 
## subset(d, listChoice == 1 & subjCode %in% perfect_final_accuracy_subjects)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1723.0   1781.0   -851.5   1703.0     2420 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -11.7263   0.0863   0.2002   0.4030   2.8142 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev. Corr       
##  subjCode    (Intercept)         0.0920585 0.30341             
##              hfTrial             3.7867560 1.94596   0.12      
##              angleDiffFromMatchC 0.0008041 0.02836  -0.97  0.14
##  targetLabel (Intercept)         0.0809354 0.28449             
## Number of obs: 2430, groups:  subjCode, 42; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.33787    0.12473  18.743  < 2e-16 ***
## hfTrial              0.98028    0.32847   2.984  0.00284 ** 
## angleDiffFromMatchC -0.19877    0.01388 -14.317  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial      0.060       
## anglDffFrMC -0.605  0.071
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          2.0934018  2.5823363
## hfTrial              0.3364831  1.6240771
## angleDiffFromMatchC -0.2259792 -0.1715561
## maximal model yields a singular fit
## model with simpler random-effects structure (random slopes removed to allow convergence) yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Controlling for compass direction character length

The words given to each of the compass directions varied in character length (and therefore perhaps in how easy they are to produce/ type). Beyond randomly assigning compass directions and counterbalancing their roles across participants, we also fit all models with by-item random effects to ensure that the effect of frequency generalizes across items. In the following model, we also explicitly control for character length to ensure that the effects hold even after accounting for character length of the nearest/ target compass direction.

# Full model has convergence issues (Unlike other models, standard errors appear to be dramatically underestimated, presumably due to singular fit issue)
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))

#Simplified model removing by-participant random slope for angleDiffFromMatchC (i.e. slope not relevant to the effect of interest; results are consistent, with more plausible standard errors)
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial+nearestLabel_length|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + nearestLabel_length +  
##     (1 + hfTrial + nearestLabel_length | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2233.7   2300.4  -1105.9   2211.7     3142 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -14.7983   0.0843   0.1970   0.3892   2.7868 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         5.3085   2.3040              
##              hfTrial             4.0622   2.0155    0.10      
##              nearestLabel_length 0.2928   0.5411   -1.00 -0.10
##  targetLabel (Intercept)         0.1397   0.3738              
## Number of obs: 3153, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.11938    0.61525   3.445 0.000572 ***
## hfTrial              1.19682    0.30234   3.959 7.54e-05 ***
## angleDiffFromMatchC -0.19112    0.01146 -16.679  < 2e-16 ***
## nearestLabel_length  0.03820    0.14284   0.267 0.789132    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial      0.057              
## anglDffFrMC -0.104  0.012       
## nrstLbl_lng -0.979 -0.048  0.012
confint(m,method="Wald")[8:11,]
##                          2.5 %     97.5 %
## (Intercept)          0.9135186  3.3252364
## hfTrial              0.6042431  1.7893949
## angleDiffFromMatchC -0.2135754 -0.1686598
## nearestLabel_length -0.2417550  0.3181551

Controlling for number of training blocks

Participants varied in the duration of their training. The extent to which participants were trained on the compass directions may influence the degree to which participants exhibited an effect of frequency on lexical selection. In the main logistic mixed-effects analyses demonstrating the effect of word frequency on lexical selection, we also fit a model controlling for differences in training duration by including the number of training blocks as a fixed effect.

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+num_pairlearn_blocks+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + num_pairlearn_blocks +  
##     (1 + hfTrial + angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2246.3   2313.0  -1112.2   2224.3     3142 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -9.3731  0.0841  0.1961  0.3981  2.9868 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.192780 0.43907             
##              hfTrial             4.022202 2.00554   0.00      
##              angleDiffFromMatchC 0.001754 0.04188  -0.99  0.13
##  targetLabel (Intercept)         0.124508 0.35286             
## Number of obs: 3153, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                       Estimate Std. Error z value Pr(>|z|)    
## (Intercept)           2.280465   0.223310  10.212  < 2e-16 ***
## hfTrial               1.172905   0.301947   3.884 0.000103 ***
## angleDiffFromMatchC  -0.196813   0.013868 -14.192  < 2e-16 ***
## num_pairlearn_blocks  0.004113   0.037468   0.110 0.912583    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial      0.061              
## anglDffFrMC -0.414  0.039       
## nm_prlrn_bl -0.779 -0.031  0.035
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[8:11,]
##                            2.5 %      97.5 %
## (Intercept)           1.84278550  2.71814546
## hfTrial               0.58109934  1.76471165
## angleDiffFromMatchC  -0.22399335 -0.16963239
## num_pairlearn_blocks -0.06932193  0.07754837
## maximal model yields a singular fit
## model with simpler random-effects structure yields similar results without singular fit
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+num_pairlearn_blocks+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Checking for an interaction with distance

We also investigated whether distance interacted with frequency condition in predicting lexical selection. We find no evidence of an interaction between frequency and distance.

#full interaction model
#does not converge (boundary fit)
# m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial*angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)
#simplified random effects structure preserving critical interaction random effect (qualitatively similar results to more complex models)
m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial:angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial * angleDiffFromMatchC + (1 + hfTrial:angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   2365.1   2413.5  -1174.5   2349.1     3145 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -11.5804   0.1324   0.2476   0.4225   2.6049 
## 
## Random effects:
##  Groups      Name                        Variance Std.Dev. Corr 
##  subjCode    (Intercept)                 0.02756  0.1660        
##              hfTrial:angleDiffFromMatchC 0.03395  0.1843   -0.14
##  targetLabel (Intercept)                 0.10878  0.3298        
## Number of obs: 3153, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                             Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                  2.06008    0.11011  18.709  < 2e-16 ***
## hfTrial                      0.98023    0.14283   6.863 6.75e-12 ***
## angleDiffFromMatchC         -0.17556    0.01088 -16.131  < 2e-16 ***
## hfTrial:angleDiffFromMatchC  0.02497    0.03330   0.750    0.453    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.081              
## anglDffFrMC -0.428  0.204       
## hfTrl:nDFMC  0.084 -0.421 -0.120

Reaction Time Analysis

Descriptives

We investigated participants’ speed in responding on trials in which they chose the nearest word (thereby maximizing message alignment - analogous to RT on “correct” trials).

# splitting reaction time by word frequency on trials during the Treasure Hunt Phase
summarized_rt <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency"))%>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt)
hfTrial N rt se lower_ci upper_ci
low-frequency 793 2573.057 43.09428 2488.464 2657.649
high-frequency 1794 2289.222 26.38723 2237.469 2340.975
summarized_rt_block <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("block","hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency")) %>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt_block)
block hfTrial N rt se lower_ci upper_ci
ambig low-frequency 540 2602.433 40.06542 2523.729 2681.136
ambig high-frequency 622 2342.769 36.58428 2270.925 2414.613
clear low-frequency 73 2537.279 112.83457 2312.348 2762.211
clear high-frequency 392 2339.341 42.38928 2256.002 2422.681
clear2 low-frequency 180 2499.439 71.30080 2358.740 2640.137
clear2 high-frequency 780 2221.334 29.79703 2162.842 2279.826

Linear mixed-effects model

We fit a linear mixed-effect model predicting participants’ reaction times from Word Frequency (centered; High = -0.5 vs. Low = -0.5) and Distance from Nearest Principal Direction with the same random effects structure as above.

#RT effect on trials in which nearest word is chosen
#maximal model does not converge, so remove least important
m=lmer(rt~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: 
## rt ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial + angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 42024.1
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.0537 -0.6855 -0.2333  0.4570  4.8537 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev. Corr       
##  subjCode    (Intercept)          93217.39 305.315             
##              hfTrial              46824.11 216.389  -0.08      
##              angleDiffFromMatchC     43.11   6.566  -0.07 -0.50
##  targetLabel (Intercept)          39541.97 198.852             
##  Residual                        624253.21 790.097             
## Number of obs: 2587, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error t value
## (Intercept)         2445.809     65.002  37.627
## hfTrial             -257.780     46.519  -5.541
## angleDiffFromMatchC    7.877      2.823   2.790
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.119       
## anglDffFrMC -0.024  0.080
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                             F Df Df.res    Pr(>F)    
## (Intercept)         1414.1896  1 39.846 < 2.2e-16 ***
## hfTrial               30.5301  1 50.879 1.131e-06 ***
## angleDiffFromMatchC    7.7386  1 52.572  0.007489 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
confint(m,method="Wald")
##                           2.5 %     97.5 %
## .sig01                       NA         NA
## .sig02                       NA         NA
## .sig03                       NA         NA
## .sig04                       NA         NA
## .sig05                       NA         NA
## .sig06                       NA         NA
## .sig07                       NA         NA
## .sigma                       NA         NA
## (Intercept)         2318.407280 2573.21116
## hfTrial             -348.956003 -166.60303
## angleDiffFromMatchC    2.344337   13.40974
#no interaction with block
#include highest order interaction terms as random slopes
m=lmer(rt~(hfTrial+angleDiffFromMatchC)*blockC+(1+hfTrial:blockC+angleDiffFromMatchC:blockC|subjCode)+(1|targetLabel),data=subset(d,matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: rt ~ (hfTrial + angleDiffFromMatchC) * blockC + (1 + hfTrial:blockC +  
##     angleDiffFromMatchC:blockC | subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 42006.4
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -1.9036 -0.6989 -0.2239  0.4879  4.8386 
## 
## Random effects:
##  Groups      Name                       Variance Std.Dev. Corr       
##  subjCode    (Intercept)                110441.2 332.327             
##              hfTrial:blockC               2268.7  47.631   1.00      
##              blockC:angleDiffFromMatchC     71.3   8.444  -1.00 -1.00
##  targetLabel (Intercept)                 36415.6 190.829             
##  Residual                               636182.2 797.610             
## Number of obs: 2587, groups:  subjCode, 55; targetLabel, 18
## 
## Fixed effects:
##                            Estimate Std. Error t value
## (Intercept)                2478.782     71.105  34.861
## hfTrial                    -245.381     37.263  -6.585
## angleDiffFromMatchC           2.658      4.989   0.533
## blockC                       74.617     63.637   1.173
## hfTrial:blockC                8.089     73.530   0.110
## angleDiffFromMatchC:blockC  -13.521     10.055  -1.345
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC blockC hfTr:C
## hfTrial     -0.098                            
## anglDffFrMC -0.026 -0.033                     
## blockC       0.005  0.226 -0.817              
## hfTrl:blckC  0.154 -0.143 -0.021 -0.214       
## anglDfFMC:C -0.431 -0.026  0.039 -0.055 -0.043
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                                    F Df  Df.res    Pr(>F)    
## (Intercept)                1213.8263  1   52.92 < 2.2e-16 ***
## hfTrial                      43.0535  1 2519.70 6.442e-11 ***
## angleDiffFromMatchC           0.2823  1 2504.20    0.5952    
## blockC                        1.3646  1 2487.64    0.2429    
## hfTrial:blockC                0.0120  1   73.61    0.9130    
## angleDiffFromMatchC:blockC    1.7977  1   53.24    0.1857    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Plot

Plot the effect of training frequency on word/ compass direction choice.

#refit model without centering angle for simpler plotting,simplified random effects structure due to non-convergence (coefficients roughly equivalent, slight differences on second decimal point)
m <- glmer(matchChoice~hfTrial+angleDiffFromMatch+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))

pX <- expand.grid(angleDiffFromMatch=seq(0,22.5,by=0.1),hfTrial=c(-0.5,0.5))

predictions <- predictSE(m,pX,re.form=NA, type="response")
pX$fit <- predictions$fit
pX$se.fit <- predictions$se.fit

#### Three different plot design options ####

# Plot 1

q <- ggplot(subset(d, trialType=="test"),aes(angleDiffFromMatch,matchChoice,color=as.character(hfTrial)))+
  geom_jitter(width=0.5,height=0.03,alpha=0.2)+
  #geom_violinh(aes(y=matchChoice,group=hfTrial),scale="count",width=0.5)+
  geom_smooth(data=pX,aes(y=fit,ymax=fit+se.fit,ymin=fit-se.fit,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing nearest word")+
  scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
                     breaks=c(-0.5,0.5),
                     labels=c("Low-Frequency","High-Frequency"),direction=-1)+
  scale_fill_brewer(palette="Set1",name="Frequency of Nearest Word",
                     breaks=c(-0.5,0.5),
                     labels=c("Low-Frequency","High-Frequency"),direction=-1)+
  xlab("Distance from nearest word")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))+
  ylim(-0.05,1.05)
ggsave(here::here("plots","exp3_frequencyEffect_old.jpg"), width=9, height=6)

# Plot 2

p_freq3 <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, alpha=0.3,shape=19,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 0.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
p_freq3

ggsave(here::here("plots","exp3_frequencyEffect.jpg"), width=9, height=6)

# Plot 3

#alternate
p <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, shape=19,alpha=0.2,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 1.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.75,alpha=0.4, color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.75,alpha=0.4,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
ggsave(here::here("plots","exp3_frequencyEffect_alternate.jpg"), width=9, height=6)

Experiment 4

#load data
d <- filter(all_data,version=="exp4")

#exclude subjects
excludeList <- c()
d <- subset(d, !(subjCode %in% excludeList))

Demographics

Overview over the demographics of participants in Experiment 4.

#demographics
subjDemographics <- d %>%
  select(subjCode,Gender,Age,NativeLang,SecondLangYN) %>%
  unique() %>%
  summarize(
    N=n(),
    gender_f=sum(Gender=="Female"),
    mean_age=round(mean(Age,na.rm=T),2),
    sd_age=round(sd(Age,na.rm=T),2),
    min_age=round(min(Age,na.rm=T),2),
    max_age=round(max(Age,na.rm=T),2),
    native_english=sum(NativeLang=="Yes"),
    language_besides_english=sum(SecondLangYN=="Yes"),
  )

kable(subjDemographics)
N gender_f mean_age sd_age min_age max_age native_english language_besides_english
43 24 18.72 0.88 18 21 43 5

Manipulation check

In Experiment 4, participants were first familiarized with the compass directions in order to unconfound visual familiarity with specific compass directions with naming experience with those compass directions. During Compass Practice Block, the compass directions for which a high-frequency name would later be assigned appeared four times less than the compass directions for which a low-frequency name would be assigned in a training task that did not involve assigning names to the compass direction.

Below, we verify visually that the manipulation was appropriately applied to each participant (to unconfound visual familiarity and naming experience), and summarize participants’ performance during the compass direction memory task.

#manipulation check
#is angle frequency expsoure during learning balanced
ggplot(subset(d,trialType=="pairLearn"|trialType=="nonvLearn"),aes(angle,fill=trialType))+
  geom_histogram(position=position_dodge())+
  facet_wrap(~subjCode)

ggsave(here::here("plots","exp4_learningAnglesManCheck.jpg"), width=9, height=6)

#generate by-subject accuracy for each block (repeated training blocks are averaged together)
subjAcc <- d %>%
  group_by(subjCode,trialType) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode)),
    rt = mean(rt,na.rm=T)) %>%
  ungroup()

#accuracy on angle memory task
overallNonVLearn <- subjAcc %>%
  filter(trialType=="nonvLearn") %>%
  summarize(acc=mean(accuracy,na.rm=T),
            sd = sd(accuracy),
            rt=mean(rt))

kable(overallNonVLearn)
acc sd rt
0.9765116 0.0382899 1669.875

Pair Learning Accuracy

Overall Pair Learning Accuracy

Overview of participants’ performance during the Training Phase in which word participants learn each of the 8 compass directions.

#generate by-subject accuracy for each block (repeated training blocks are averaged together)
subjAcc <- d %>%
  group_by(subjCode,trialType) %>%
  summarize(accuracy=mean(isRight,na.rm=T),
              numTrials=sum(!is.na(subjCode)),
              rt = mean(rt,na.rm=T)) %>%
  ungroup()

#Overall Accuracy Pair Learning
overallPairAcc <- subjAcc %>%
  filter(trialType=="pairLearn") %>%
  summarize(
    acc=mean(accuracy,na.rm=T),
    sd = sd(accuracy),
    num_trials_avg = mean(numTrials),
    num_trials_sd = sd(numTrials),
    num_blocks_avg = mean(numTrials/20),
    num_blocks_sd= sd(numTrials/20))
kable(overallPairAcc)
acc sd num_trials_avg num_trials_sd num_blocks_avg num_blocks_sd
0.93 0.0767184 100 0 5 0

Accuracy by Block

#pair learning over time
#summarize by block
subj_pair_accuracy_by_block <- d %>%
  filter(trialType=="pairLearn"&!is.na(pairLearnBlockNum)) %>%
  group_by(subjCode,pairLearnBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_pair_accuracy_by_block <- subj_pair_accuracy_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("pairLearnBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(pairLearnBlockNum=as.numeric(as.character(pairLearnBlockNum)))

#one plot each subject is a line
pair_accuracy_by_block_exp4 <- ggplot(overall_pair_accuracy_by_block,aes(pairLearnBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.8))+
  scale_x_continuous(breaks=1:20)+
  scale_y_continuous(breaks=seq(0.5,1,0.1))+
  coord_cartesian(ylim = c(0.45, 1.05))+
  geom_hline(yintercept=0.5,linetype="dashed")+
  annotate("text",x=2,y=0.55,label="chance")+
  xlab("Word Learning Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Word Recall by Block

subj_training_recall_by_block <- d %>%
  filter(trialType=="name"&!is.na(nameBlockNum)) %>%
  group_by(subjCode,nameBlockNum) %>%
  summarize(
    accuracy=mean(isRight,na.rm=T),
    numTrials=sum(!is.na(subjCode))) %>%
  ungroup()

overall_training_recall_by_block <- subj_training_recall_by_block %>%
  summarySEwithin(measurevar="accuracy",withinvars=c("nameBlockNum"),idvar="subjCode") %>%
  mutate(lower_ci=accuracy-ci,
         upper_ci=accuracy+ci) %>%
  mutate(nameBlockNum=as.numeric(as.character(nameBlockNum)))

#one plot each subject is a line
training_recall_by_block_exp4 <- ggplot(overall_training_recall_by_block,aes(nameBlockNum,y=accuracy,label=N))+
  geom_point()+
  geom_line()+
  geom_errorbar(aes(ymin=lower_ci,ymax=upper_ci),width=0)+
  geom_label(aes(y=0.25))+
  scale_x_continuous(breaks=1:20)+
  xlab("Training - Word Recall Block")+
  ylab("Accuracy")+
  ylim(0,1.05)

Final word retention

Timed Retention Test

Participants’ performance during the Timed Retention test at the conclusion of the experiment.

Accuracy

#summarize subject accuracy by frequency
subjAccFreq <- d %>%
  group_by(subjCode,block,freq) %>%
  summarize(accuracy=mean(isRight,na.rm=T),
            rt = mean(rt,na.rm=T)) %>%
  ungroup()

testXAcc <-  summarySEwithin(data=subset(subjAccFreq,block=="test_x"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
testXAcc$lowerCI <-  testXAcc$accuracy - testXAcc$ci
testXAcc$upperCI <-  testXAcc$accuracy + testXAcc$ci
testXAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 43 0.9244186 0.0212296 0.8815756 0.9672616
lf 43 0.8313953 0.0212296 0.7885524 0.8742383
#t-test
t.test(subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$accuracy[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$accuracy[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = 3.0984, df = 42, p-value = 0.003464
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  0.03243413 0.15361238
## sample estimates:
## mean of the differences 
##              0.09302326

Reaction Times

# reaction times
testXRT <-  summarySEwithin(subset(subjAccFreq,block=="test_x"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
testXRT$lowerCI <- testXRT$rt - testXRT$ci
testXRT$upperCI <- testXRT$rt + testXRT$ci
testXRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 43 2439.123 56.79235 2324.511 2553.734
lf 43 2600.677 56.79235 2486.065 2715.289
#t-test
t.test(subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="hf"],
       subset(subjAccFreq,block=="test_x")$rt[subset(subjAccFreq,block=="test_x")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "hf"] and subset(subjAccFreq, block == "test_x")$rt[subset(subjAccFreq, block == "test_x")$freq == "lf"]
## t = -2.0115, df = 42, p-value = 0.05072
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -323.6397997    0.5307484
## sample estimates:
## mean of the differences 
##               -161.5545

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(testXAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(testXRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="test_x"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="test_x"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp4_testXCheck.jpg"), width=9, height=6)

Untimed Retention Test

Participants’ performance on the Untimed Retention test at the conclusion of the experiment.

Accuracy

nameCheckAcc <-  summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="accuracy",withinvars=c("freq"),idvar="subjCode")
nameCheckAcc$lowerCI <-  nameCheckAcc$accuracy - nameCheckAcc$ci
nameCheckAcc$upperCI <-  nameCheckAcc$accuracy + nameCheckAcc$ci
nameCheckAcc %>%
  select(-sd,-ci,-accuracy_norm) %>%
  kable()
freq N accuracy se lowerCI upperCI
hf 43 0.9767442 0.0202398 0.9358987 1.0175897
lf 43 0.9186047 0.0202398 0.8777591 0.9594502
#t-test
t.test(subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$accuracy[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$accuracy[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = 2.0312, df = 42, p-value = 0.0486
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  0.0003752313 0.1159038385
## sample estimates:
## mean of the differences 
##              0.05813953

Reaction Times

# reaction times
nameCheckRT <-  summarySEwithin(subset(subjAccFreq,block=="name_check"), measurevar="rt",withinvars=c("freq"),idvar="subjCode")
nameCheckRT$lowerCI <-  nameCheckRT$rt - nameCheckRT$ci
nameCheckRT$upperCI <-  nameCheckRT$rt + nameCheckRT$ci
nameCheckRT %>%
  select(-sd,-ci,-rt_norm) %>%
  kable()
freq N rt se lowerCI upperCI
hf 43 2541.706 103.6386 2332.555 2750.857
lf 43 2901.322 103.6386 2692.170 3110.473
#t-test
t.test(subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="hf"],
       subset(subjAccFreq,block=="name_check")$rt[subset(subjAccFreq,block=="name_check")$freq=="lf"],paired=T)
## 
##  Paired t-test
## 
## data:  subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "hf"] and subset(subjAccFreq, block == "name_check")$rt[subset(subjAccFreq, block == "name_check")$freq == "lf"]
## t = -2.4536, df = 42, p-value = 0.01837
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -655.40004  -63.83147
## sample estimates:
## mean of the differences 
##               -359.6158

Plotting Accuracy and Reaction Times

#plot
p1 <- ggplot(nameCheckAcc,aes(freq,accuracy,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  theme_classic(base_size=20)+
  theme(legend.position="none")+
  ylim(0,1.05)

p2 <- ggplot(nameCheckRT,aes(freq,rt,color=freq,fill=freq))+
  geom_bar(stat="identity",alpha=0.5,size=1.2)+ 
  geom_violin(data=subset(subjAccFreq,block=="name_check"),fill=NA,alpha=0)+
  geom_jitter(data=subset(subjAccFreq,block=="name_check"),width=0.2,height=0.03)+
  geom_errorbar(aes(ymin=lowerCI,ymax=upperCI),width=0.05,color="black",size=1.2)+
    #scale_color_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                     #values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency",
  #                   breaks=c("hf","lf"),
  #                   labels=c("high-frequency","low-frequency"))+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency",
                     breaks=c("hf","lf"),
                     labels=c("high-frequency","low-frequency"))+
  scale_x_discrete(name="Frequency",breaks=c("hf","lf"),labels=c("high-\nfrequency","low-\nfrequency"))+
  ylab("Reaction Time (ms)")+
  theme_classic(base_size=20)+
  theme(legend.position="none")
p <- plot_grid(p1,p2)
p

ggsave(here::here("plots","exp4_finalNameCheck.jpg"), width=9, height=6)

Frequency Effect on Word Choice

Main Model

As in Experiments 1-3, we considered participants’ likelihood of choosing the word for the nearest compass direction, dependent on whether that compass direction was a high- or a low-frequency word, while controlling for the distance from the nearest learned compass direction. We focused specifically on low-frequency/high-frequency trials, in which a compass direction was tested in between a low-frequency and a high-frequency trained direction.

As a conservative test, we retained only trials in which participants chose one of the two principal direction words within 45° of the stimulus direction (93% of all low-frequency/high-frequency trials).

# full model yields a convergence warning ((degenerate Hessian) - 
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

#simplified model removing random slope for angleDiffFromMatchC yields consistent results (and no convergence warning)
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1794.8   1835.3   -890.4   1780.8     2411 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -6.1425  0.0918  0.2128  0.4097  1.9726 
## 
## Random effects:
##  Groups      Name        Variance Std.Dev. Corr
##  subjCode    (Intercept) 0.08136  0.2852       
##              hfTrial     3.27343  1.8093   0.12
##  targetLabel (Intercept) 0.16378  0.4047       
## Number of obs: 2418, groups:  subjCode, 43; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.26443    0.14252  15.888   <2e-16 ***
## hfTrial              0.77240    0.30826   2.506   0.0122 *  
## angleDiffFromMatchC -0.20290    0.01269 -15.993   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial      0.051       
## anglDffFrMC -0.454  0.017
#confidence interval
confint(m,method="Wald")[5:7,]
##                          2.5 %     97.5 %
## (Intercept)          1.9850879  2.5437721
## hfTrial              0.1682224  1.3765766
## angleDiffFromMatchC -0.2277621 -0.1780325
#calculate shift in x-axis units (degrees of angle)
shift_x <- -(summary(m)$coefficients[1,1]+0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*summary(m)$coefficients[2,1])/summary(m)$coefficients[3,1]
#low 95% CI
shift_x_lower <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[5:7,][2,1])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[5:7,][2,1])/summary(m)$coefficients[3,1]
#high 95% CI
shift_x_upper <- -(summary(m)$coefficients[1,1]+0.5*confint(m,method="Wald")[5:7,][2,2])/summary(m)$coefficients[3,1] + (summary(m)$coefficients[1,1]-0.5*confint(m,method="Wald")[5:7,][2,2])/summary(m)$coefficients[3,1]

This effect corresponded to an estimated 3.81° shift (95% CI = [0.83°, 6.78°]) in participants’ decision boundary for high-frequency words as compared to low-frequency words.

Robustness Checks

Controlling for final retention accuracy of labels on each trial

To ensure that the frequency effect is not an artifact of participants’ being slightly more likely to forget the low-frequency labels, we first re-fit the model while controlling for participants’ accuracy during the Untimed Retention Test for the two (nearby) compass directions involved in each trial.

#controlling for accuracy for nearby labels
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels+(1+hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels +  
##     (1 + hfTrial + angleDiffFromMatchC + finalAccuracyNearbyLabels |  
##         subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1801.7   1888.5   -885.8   1771.7     2403 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -7.1348  0.0957  0.2100  0.4058  2.0548 
## 
## Random effects:
##  Groups      Name                      Variance Std.Dev. Corr             
##  subjCode    (Intercept)               0.00000  0.00000                   
##              hfTrial                   3.30423  1.81775    NaN            
##              angleDiffFromMatchC       0.00174  0.04171    NaN  0.31      
##              finalAccuracyNearbyLabels 0.13984  0.37395    NaN  0.05 -0.52
##  targetLabel (Intercept)               0.13987  0.37400                   
## Number of obs: 2418, groups:  subjCode, 43; targetLabel, 18
## 
## Fixed effects:
##                           Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                1.12025    0.42743   2.621  0.00877 ** 
## hfTrial                    0.77964    0.31095   2.507  0.01217 *  
## angleDiffFromMatchC       -0.20524    0.01512 -13.576  < 2e-16 ***
## finalAccuracyNearbyLabels  1.23331    0.44153   2.793  0.00522 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.020              
## anglDffFrMC -0.095  0.125       
## fnlAccrcyNL -0.941  0.036 -0.088
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
confint(m,method="Wald")[12:15,]
##                                2.5 %     97.5 %
## (Intercept)                0.2825023  1.9579906
## hfTrial                    0.1701761  1.3890973
## angleDiffFromMatchC       -0.2348646 -0.1756064
## finalAccuracyNearbyLabels  0.3679288  2.0986984
# full model yields a singular fit - simplified model removing random slopes for angleDiffFromMatchC and finalAccuracyNearbyLabels yields consistent results (and no singular fit warning)
# m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+finalAccuracyNearbyLabels + (1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)

Including only participants with perfect recall for all compass directions at the end of the experiment

We next re-fit the same model using a stricter inclusion criterion, including only participants who recalled all items correctly during the Untimed Retetion test. Here, unlike in the previous three experiments, we found that the effect of frequency did not hold after removing 10 participants who did not have perfect accuracy on the Untimed Retention test.

final_accuracy <- d %>%
  filter(trialType=="finalName") %>%
  group_by(subjCode,trialType) %>%
  summarize(N=n(),accuracy=mean(isRight)) %>%
  ungroup()

#select only participants with perfect recall on the final test block
perfect_final_accuracy_subjects <- as.character(filter(final_accuracy,accuracy==1)$subjCode)

#Fit model
m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_final_accuracy_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: 
## subset(d, listChoice == 1 & subjCode %in% perfect_final_accuracy_subjects)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1370.8   1426.0   -675.4   1350.8     1839 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -7.8518  0.0964  0.2087  0.4125  1.8651 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr       
##  subjCode    (Intercept)         0.126882 0.35621             
##              hfTrial             2.413463 1.55353  -0.12      
##              angleDiffFromMatchC 0.001321 0.03635  -0.75 -0.01
##  targetLabel (Intercept)         0.034931 0.18690             
## Number of obs: 1849, groups:  subjCode, 33; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.40085    0.14550  16.500   <2e-16 ***
## hfTrial              0.42380    0.31291   1.354    0.176    
## angleDiffFromMatchC -0.22675    0.01765 -12.849   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.043       
## anglDffFrMC -0.721  0.008
confint(m,method="Wald")[8:10,]
##                          2.5 %     97.5 %
## (Intercept)          2.1156626  2.6860314
## hfTrial             -0.1894847  1.0370902
## angleDiffFromMatchC -0.2613393 -0.1921644

Selecting only participants with perfect recall on the final Word Learning block

Unlike Exps 1-3, participants in Exp 4 saw a fixed number of learning trials. Therefore, not all participants reached perfect accuracy by the end of the training phase. We therefore re-ran the main model including only participants with perfect recall on the final Word Learning block (i.e., participants who entered the test phase/ “Treasure Hunt” having scored perfectly on all compass directions).

subj_acc_name_block <- d %>%
  filter(trialType=="name"&block=="init"&!(is.na(nameBlockNum))) %>%
  group_by(subjCode,nameBlockNum) %>%
  summarize(N=n(),accuracy=mean(isRight)) %>%
  ungroup()

#select only participants with perfect recall on the final Word Learning block
perfect_learning_subjects <- as.character(filter(subj_acc_name_block,nameBlockNum==5&accuracy==1)$subjCode)

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1&subjCode %in% perfect_learning_subjects),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial +  
##     angleDiffFromMatchC | subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1 & subjCode %in% perfect_learning_subjects)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1218.7   1272.6   -599.4   1198.7     1613 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -6.7350  0.0970  0.2075  0.4154  1.7457 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev. Corr       
##  subjCode    (Intercept)         0.1065132 0.3264              
##              hfTrial             3.0559540 1.7481   -0.04      
##              angleDiffFromMatchC 0.0009061 0.0301   -0.54  0.55
##  targetLabel (Intercept)         0.2031222 0.4507              
## Number of obs: 1623, groups:  subjCode, 29; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.28376    0.17533  13.025   <2e-16 ***
## hfTrial              0.73460    0.36701   2.002   0.0453 *  
## angleDiffFromMatchC -0.19956    0.01724 -11.574   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial      0.003       
## anglDffFrMC -0.530  0.174
confint(m,method="Wald")[8:10,]
##                           2.5 %     97.5 %
## (Intercept)          1.94011610  2.6273990
## hfTrial              0.01528331  1.4539178
## angleDiffFromMatchC -0.23335627 -0.1657692

Controlling for compass direction character length

The words given to each of the compass directions varied in character length (and therefore perhaps in how easy they are to produce/ type). Beyond randomly assigning compass directions and counterbalancing their roles across participants, we also fit all models with by-item random effects to ensure that the effect of frequency generalizes across items. In the following model, we also explicitly control for character length to ensure that the effects hold even after accounting for character length of the nearest/ target compass direction.

m <- glmer(matchChoice~hfTrial+angleDiffFromMatchC+nearestLabel_length+(1+hfTrial+angleDiffFromMatchC+nearestLabel_length|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ hfTrial + angleDiffFromMatchC + nearestLabel_length +  
##     (1 + hfTrial + angleDiffFromMatchC + nearestLabel_length |  
##         subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1777.5   1864.3   -873.7   1747.5     2403 
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -6.2867  0.0808  0.1917  0.3867  1.9896 
## 
## Random effects:
##  Groups      Name                Variance Std.Dev. Corr             
##  subjCode    (Intercept)         9.275998 3.04565                   
##              hfTrial             4.279920 2.06880   0.24            
##              angleDiffFromMatchC 0.001115 0.03339   0.12  0.59      
##              nearestLabel_length 0.513307 0.71645  -0.99 -0.26 -0.20
##  targetLabel (Intercept)         0.211573 0.45997                   
## Number of obs: 2418, groups:  subjCode, 43; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          2.22324    0.79270   2.805  0.00504 ** 
## hfTrial              0.80548    0.35238   2.286  0.02227 *  
## angleDiffFromMatchC -0.21190    0.01528 -13.869  < 2e-16 ***
## nearestLabel_length  0.04229    0.18352   0.230  0.81775    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial      0.143              
## anglDffFrMC -0.080  0.180       
## nrstLbl_lng -0.978 -0.150 -0.031
confint(m,method="Wald")[12:15,]
##                          2.5 %     97.5 %
## (Intercept)          0.6695770  3.7769124
## hfTrial              0.1148197  1.4961369
## angleDiffFromMatchC -0.2418455 -0.1819543
## nearestLabel_length -0.3174086  0.4019904

Checking for an interaction with distance

We also investigated whether distance interacted with frequency condition in predicting lexical selection. We find no evidence of an interaction between frequency and distance.

#full interaction model
#does not converge (boundary fit)
# m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial*angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
# summary(m)
#simplified random effects structure preserving critical interaction random effect (qualitatively similar results to more complex models, though here some more non-converging complex models show a significant interaction w/ a similar effect magnitude)
m <- glmer(matchChoice~hfTrial*angleDiffFromMatchC+(1+hfTrial:angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: 
## matchChoice ~ hfTrial * angleDiffFromMatchC + (1 + hfTrial:angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   1874.0   1920.3   -929.0   1858.0     2410 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -17.3981   0.1189   0.2530   0.4655   1.5535 
## 
## Random effects:
##  Groups      Name                        Variance Std.Dev. Corr 
##  subjCode    (Intercept)                 0.04325  0.2080        
##              hfTrial:angleDiffFromMatchC 0.02413  0.1553   -0.23
##  targetLabel (Intercept)                 0.08691  0.2948        
## Number of obs: 2418, groups:  subjCode, 43; targetLabel, 18
## 
## Fixed effects:
##                             Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                  2.04593    0.11436  17.891  < 2e-16 ***
## hfTrial                      0.92301    0.16220   5.691 1.27e-08 ***
## angleDiffFromMatchC         -0.18400    0.01206 -15.261  < 2e-16 ***
## hfTrial:angleDiffFromMatchC -0.04767    0.03389  -1.406     0.16    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC
## hfTrial     -0.022              
## anglDffFrMC -0.491  0.068       
## hfTrl:nDFMC  0.001 -0.476 -0.071

Interactions between Experiment

We observed no interaction between Experiment 3 and Experiment 4 (i.e., controllining for amount of visual experience did not significantly reduce the magnitude of the effect relative to Experiment 3, which was identical to Experiment 4 except for the initial training with the visual stimuli).

all_data <- all_data %>% mutate(versionC=case_when(
  version=="exp3" ~-0.5,
  version == "exp4"~ 0.5,
  TRUE ~ NA_real_)) 
#maximal by-subjects random effects structure does not converge; simplify by-subject random slopes
#m <- glmer(matchChoice~(hfTrial+angleDiffFromMatchC)*versionC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(all_data, listChoice==1& version  %in% c("exp3","exp4")),family=binomial,glmerControl(optimizer="bobyqa"))
m <- glmer(matchChoice~(hfTrial+angleDiffFromMatchC)*versionC+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(all_data, listChoice==1& version  %in% c("exp3","exp4")),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ (hfTrial + angleDiffFromMatchC) * versionC + (1 +  
##     hfTrial | subjCode) + (1 | targetLabel)
##    Data: subset(all_data, listChoice == 1 & version %in% c("exp3", "exp4"))
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   4035.4   4101.7  -2007.7   4015.4     5561 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -13.0702   0.0913   0.2088   0.4082   3.2051 
## 
## Random effects:
##  Groups      Name        Variance Std.Dev. Corr
##  subjCode    (Intercept) 0.06212  0.2492       
##              hfTrial     3.51033  1.8736   0.11
##  targetLabel (Intercept) 0.10688  0.3269       
## Number of obs: 5571, groups:  subjCode, 98; targetLabel, 18
## 
## Fixed effects:
##                               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                   2.238700   0.102873  21.762  < 2e-16 ***
## hfTrial                       0.962216   0.212321   4.532 5.85e-06 ***
## angleDiffFromMatchC          -0.194797   0.008449 -23.056  < 2e-16 ***
## versionC                      0.061009   0.128676   0.474    0.635    
## hfTrial:versionC             -0.408764   0.417910  -0.978    0.328    
## angleDiffFromMatchC:versionC -0.015661   0.016674  -0.939    0.348    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC versnC hfTr:C
## hfTrial      0.053                            
## anglDffFrMC -0.407  0.017                     
## versionC     0.085 -0.011 -0.088              
## hfTrl:vrsnC -0.008  0.114  0.001  0.044       
## anglDfFMC:C -0.058  0.000  0.116 -0.608  0.031

To also check for any overall differences across experiment version, we also tested for an interaction with experiment across the entire dataset (Exps 1-4). There was no significant difference in the magnitude of the frequency effect across experiments.

#model including the more maximal by-subjects random effects structure does not converge (boundary fit). We therefore prune the model while retaining random slopes for the key effect of interest (hfTrial, i.e. the coefficient testing the frequency effect)
#m <- glmer(matchChoice~(hfTrial+angleDiffFromMatchC)*version+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),
#           data=subset(all_data, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
m <- glmer(matchChoice~(hfTrial+angleDiffFromMatchC)*version+(1+hfTrial|subjCode)+(1|targetLabel),
           data=subset(all_data, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))
summary(m)
## Generalized linear mixed model fit by maximum likelihood (Laplace
##   Approximation) [glmerMod]
##  Family: binomial  ( logit )
## Formula: matchChoice ~ (hfTrial + angleDiffFromMatchC) * version + (1 +  
##     hfTrial | subjCode) + (1 | targetLabel)
##    Data: subset(all_data, listChoice == 1)
## Control: glmerControl(optimizer = "bobyqa")
## 
##      AIC      BIC   logLik deviance df.resid 
##   8476.5   8594.0  -4222.2   8444.5    11400 
## 
## Scaled residuals: 
##      Min       1Q   Median       3Q      Max 
## -10.8925   0.0998   0.2159   0.4250   3.4420 
## 
## Random effects:
##  Groups      Name        Variance Std.Dev. Corr 
##  subjCode    (Intercept) 0.05768  0.2402        
##              hfTrial     2.83355  1.6833   -0.05
##  targetLabel (Intercept) 0.01278  0.1130        
## Number of obs: 11416, groups:  subjCode, 181; targetLabel, 18
## 
## Fixed effects:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                      2.31044    0.09285  24.883  < 2e-16 ***
## hfTrial                          0.77291    0.29026   2.663  0.00775 ** 
## angleDiffFromMatchC             -0.22109    0.01136 -19.469  < 2e-16 ***
## versionexp2                     -0.43016    0.12378  -3.475  0.00051 ***
## versionexp3                     -0.11804    0.12177  -0.969  0.33236    
## versionexp4                     -0.08067    0.13011  -0.620  0.53525    
## hfTrial:versionexp2              0.50422    0.40372   1.249  0.21169    
## hfTrial:versionexp3              0.33617    0.38547   0.872  0.38316    
## hfTrial:versionexp4             -0.05988    0.40721  -0.147  0.88309    
## angleDiffFromMatchC:versionexp2  0.04297    0.01609   2.670  0.00758 ** 
## angleDiffFromMatchC:versionexp3  0.03759    0.01576   2.385  0.01708 *  
## angleDiffFromMatchC:versionexp4  0.02110    0.01678   1.258  0.20850    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC vrsnx2 vrsnx3 vrsnx4 hfTr:2 hfTr:3 hfTr:4
## hfTrial     -0.028                                                        
## anglDffFrMC -0.639  0.021                                                 
## versionexp2 -0.680  0.024  0.474                                          
## versionexp3 -0.690  0.024  0.481  0.528                                   
## versionexp4 -0.646  0.024  0.449  0.491  0.500                            
## hfTrl:vrsn2  0.023 -0.716 -0.017 -0.014 -0.015 -0.015                     
## hfTrl:vrsn3  0.024 -0.750 -0.017 -0.014 -0.015 -0.016  0.541              
## hfTrl:vrsn4  0.023 -0.710 -0.016 -0.014 -0.015 -0.032  0.512  0.537       
## anglDfFMC:2  0.446 -0.016 -0.701 -0.615 -0.342 -0.320  0.024  0.011  0.011
## anglDfFMC:3  0.456 -0.016 -0.717 -0.344 -0.634 -0.326  0.011  0.029  0.011
## anglDfFMC:4  0.428 -0.016 -0.673 -0.323 -0.329 -0.644  0.011  0.011  0.026
##             aDFMC:2 aDFMC:3
## hfTrial                    
## anglDffFrMC                
## versionexp2                
## versionexp3                
## versionexp4                
## hfTrl:vrsn2                
## hfTrl:vrsn3                
## hfTrl:vrsn4                
## anglDfFMC:2                
## anglDfFMC:3  0.507         
## anglDfFMC:4  0.476   0.486
Anova(m, type="III")
## Analysis of Deviance Table (Type III Wald chisquare tests)
## 
## Response: matchChoice
##                                Chisq Df Pr(>Chisq)    
## (Intercept)                 619.1518  1  < 2.2e-16 ***
## hfTrial                       7.0903  1   0.007750 ** 
## angleDiffFromMatchC         379.0524  1  < 2.2e-16 ***
## version                      14.0571  3   0.002828 ** 
## hfTrial:version               2.7637  3   0.429515    
## angleDiffFromMatchC:version   8.7401  3   0.032953 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Reaction Time Analysis

Descriptives

We investigated participants’ speed in responding on trials in which they chose the nearest word (thereby maximizing message alignment - analogous to RT on “correct” trials).

# splitting reaction time by word frequency on trials during the Treasure Hunt Phase
summarized_rt <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency"))%>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt)
hfTrial N rt se lower_ci upper_ci
low-frequency 620 2564.746 47.84946 2470.779 2658.713
high-frequency 1352 2261.943 28.85828 2205.331 2318.555
summarized_rt_block <- d %>%
  filter(matchChoice==1) %>%
  summarySEwithin(measurevar="rt",withinvars=c("block","hfTrial"),idvar="subjCode") %>%
  mutate(lower_ci = rt - ci,
         upper_ci = rt + ci) %>%
  mutate(hfTrial=ifelse(hfTrial==-0.5,"low-frequency","high-frequency")) %>%
  select(-sd,-ci,-rt_norm)
kable(summarized_rt_block)
block hfTrial N rt se lower_ci upper_ci
ambig low-frequency 403 2598.801 47.14588 2506.117 2691.484
ambig high-frequency 464 2334.035 38.50208 2258.374 2409.695
clear low-frequency 70 2408.039 102.19852 2204.159 2611.920
clear high-frequency 321 2254.053 48.56140 2158.514 2349.593
clear2 low-frequency 147 2546.006 73.08794 2401.559 2690.453
clear2 high-frequency 567 2207.415 32.85566 2142.881 2271.948

Linear mixed-effects model

We fit a linear mixed-effect model predicting participants’ reaction times from Word Frequency (centered; High = -0.5 vs. Low = -0.5) and Distance from Nearest Principal Direction with the same random effects structure as above.

#RT effect on trials in which nearest word is chosen
#maximal model does not converge, so remove least important
m=lmer(rt~hfTrial+angleDiffFromMatchC+(1+hfTrial+angleDiffFromMatchC|subjCode)+(1|targetLabel),data=subset(d, matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: 
## rt ~ hfTrial + angleDiffFromMatchC + (1 + hfTrial + angleDiffFromMatchC |  
##     subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 31862.2
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.2558 -0.6863 -0.2289  0.4805  3.8042 
## 
## Random effects:
##  Groups      Name                Variance  Std.Dev. Corr       
##  subjCode    (Intercept)          66297.71 257.483             
##              hfTrial              87150.92 295.213  -0.20      
##              angleDiffFromMatchC     91.33   9.556   0.11  0.19
##  targetLabel (Intercept)          31411.01 177.232             
##  Residual                        570807.10 755.518             
## Number of obs: 1972, groups:  subjCode, 43; targetLabel, 18
## 
## Fixed effects:
##                     Estimate Std. Error t value
## (Intercept)         2422.241     60.775  39.856
## hfTrial             -251.043     59.501  -4.219
## angleDiffFromMatchC   17.004      3.305   5.145
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril
## hfTrial     -0.179       
## anglDffFrMC  0.022  0.200
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                            F Df Df.res    Pr(>F)    
## (Intercept)         1585.254  1 37.614 < 2.2e-16 ***
## hfTrial               17.735  1 40.230 0.0001389 ***
## angleDiffFromMatchC   26.326  1 41.047 7.335e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
confint(m,method="Wald")
##                          2.5 %     97.5 %
## .sig01                      NA         NA
## .sig02                      NA         NA
## .sig03                      NA         NA
## .sig04                      NA         NA
## .sig05                      NA         NA
## .sig06                      NA         NA
## .sig07                      NA         NA
## .sigma                      NA         NA
## (Intercept)         2303.12474 2541.35701
## hfTrial             -367.66217 -134.42420
## angleDiffFromMatchC   10.52663   23.48047
#no interaction with block
#include highest order interaction terms as random slopes
m=lmer(rt~(hfTrial+angleDiffFromMatchC)*blockC+(1+hfTrial:blockC+angleDiffFromMatchC:blockC|subjCode)+(1|targetLabel),data=subset(d,matchChoice==1), control=lmerControl(optimizer="bobyqa"))
summary(m)
## Linear mixed model fit by REML ['lmerMod']
## Formula: rt ~ (hfTrial + angleDiffFromMatchC) * blockC + (1 + hfTrial:blockC +  
##     angleDiffFromMatchC:blockC | subjCode) + (1 | targetLabel)
##    Data: subset(d, matchChoice == 1)
## Control: lmerControl(optimizer = "bobyqa")
## 
## REML criterion at convergence: 31840
## 
## Scaled residuals: 
##     Min      1Q  Median      3Q     Max 
## -2.2920 -0.6981 -0.2110  0.5000  3.5913 
## 
## Random effects:
##  Groups      Name                       Variance Std.Dev. Corr       
##  subjCode    (Intercept)                 81565.1 285.60              
##              hfTrial:blockC              32407.8 180.02   -0.63      
##              blockC:angleDiffFromMatchC    228.5  15.11   -1.00  0.60
##  targetLabel (Intercept)                 29955.4 173.08              
##  Residual                               585226.1 765.00              
## Number of obs: 1972, groups:  subjCode, 43; targetLabel, 18
## 
## Fixed effects:
##                            Estimate Std. Error t value
## (Intercept)                2457.107     68.777  35.726
## hfTrial                    -269.471     39.695  -6.789
## angleDiffFromMatchC          27.394      5.268   5.200
## blockC                     -169.502     66.411  -2.552
## hfTrial:blockC               21.769     83.620   0.260
## angleDiffFromMatchC:blockC  -14.592     10.804  -1.351
## 
## Correlation of Fixed Effects:
##             (Intr) hfTril anDFMC blockC hfTr:C
## hfTrial     -0.095                            
## anglDffFrMC -0.055 -0.013                     
## blockC       0.046  0.189 -0.804              
## hfTrl:blckC -0.040 -0.087 -0.030 -0.179       
## anglDfFMC:C -0.519 -0.028  0.070 -0.106  0.022
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see ?isSingular
Anova(m,type="III",test="F")
## Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)
## 
## Response: rt
##                                    F Df  Df.res    Pr(>F)    
## (Intercept)                1272.9863  1   48.91 < 2.2e-16 ***
## hfTrial                      45.6900  1 1921.31 1.831e-11 ***
## angleDiffFromMatchC          26.7644  1 1866.41 2.545e-07 ***
## blockC                        6.4514  1 1911.17   0.01117 *  
## hfTrial:blockC                0.0673  1   52.95   0.79627    
## angleDiffFromMatchC:blockC    1.8122  1   42.33   0.18542    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Plot

Plot the effect of training frequency on word/ compass direction choice.

#refit model without centering angle for simpler plotting (coefficients roughly equivalent)
m <- glmer(matchChoice~hfTrial+angleDiffFromMatch+(1+hfTrial|subjCode)+(1|targetLabel),data=subset(d, listChoice==1),family=binomial,glmerControl(optimizer="bobyqa"))

pX <- expand.grid(angleDiffFromMatch=seq(0,22.5,by=0.1),hfTrial=c(-0.5,0.5))

predictions <- predictSE(m,pX,re.form=NA, type="response")
pX$fit <- predictions$fit
pX$se.fit <- predictions$se.fit

#### Three different plotting design options ####

# Plot 1

q <- ggplot(subset(d, trialType=="test"),aes(angleDiffFromMatch,matchChoice,color=as.character(hfTrial)))+
  geom_jitter(width=0.5,height=0.03,alpha=0.2)+
  #geom_violinh(aes(y=matchChoice,group=hfTrial),scale="count",width=0.5)+
  geom_smooth(data=pX,aes(y=fit,ymax=fit+se.fit,ymin=fit-se.fit,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing nearest word")+
  scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
                     breaks=c(-0.5,0.5),
                     labels=c("Low-Frequency","High-Frequency"),direction=-1)+
  scale_fill_brewer(palette="Set1",name="Frequency of Nearest Word",
                     breaks=c(-0.5,0.5),
                     labels=c("Low-Frequency","High-Frequency"),direction=-1)+
  xlab("Distance from nearest word")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))+
  ylim(-0.05,1.05)
ggsave(here::here("plots","exp4_frequencyEffect_old.jpg"), width=9, height=6)

# Plot 2

p_freq4 <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, alpha=0.3,shape=19,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 0.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.4,alpha=0.5,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
p_freq4

ggsave(here::here("plots","exp4_frequencyEffect.jpg"), width=9, height=6)

# Plot 3

#alternate
p <- ggplot(subset(d, trialType=="test"&!is.na(matchChoice)),aes(angleDiffFromMatch,as.factor(matchChoice),color=as.character(hfTrial)))+
geom_point(size = 0.5, shape=19,alpha=0.2,position = position_jitterdodge(jitter.width = 0.05,jitter.height = 0.5,
dodge.width = 1.2,
seed = 1
))+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = .3 ),scale="count",width=0.75,alpha=0.4, color=NA)+
  geom_violinh(data=subset(d, trialType=="test"&!is.na(matchChoice)&hfTrial==-0.5),aes(fill=as.character(hfTrial)),position = position_nudge(x = 0, y = -.3 ),scale="count",width=0.75,alpha=0.4,color=NA)+
  geom_smooth(data=pX,aes(y=fit*4+1,ymax=(fit+se.fit)*4+1,ymin=(fit-se.fit)*4+1,fill=as.character(hfTrial)),stat="identity")+
  theme_classic(base_size=18)+
  ylab("Probability of choosing\nnearest compass direction")+
  # scale_color_brewer(palette="Set1",name="Frequency of Nearest Word",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_color_manual(values = c("#E41A1C","#377EB8"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  # scale_fill_brewer(palette="Set1",name="Frequency of Nearest Compass Direction",
  #                    breaks=c(0.5,-0.5),
  #                    labels=c("High-Frequency","Low-Frequency"),direction=-1)+
  scale_fill_manual(values = c("#E41A1C","#BDE0ED"),
                    name="Frequency of Compass Direction",
                     breaks=c(0.5,-0.5),
                     labels=c("High-Frequency","Low-Frequency"))+
  scale_y_discrete(limits=c("0","0.25","0.5","0.75","1"))+
  xlab("Distance from nearest compass direction")+
  geom_vline(xintercept=22.5,linetype="dashed")+
  theme(legend.position=c(0.4,0.4))
ggsave(here::here("plots","exp4_frequencyEffect_alternate.jpg"), width=9, height=6)

Supplementary Materials

Word Learning

Pair Learning Accuracy by Block

plot_grid(
  pair_accuracy_by_block_exp1,
  pair_accuracy_by_block_exp2,
  pair_accuracy_by_block_exp3,
  pair_accuracy_by_block_exp4,
  ncol=2,
  labels=c("A","B","C","D"))

ggsave(here::here("plots","pair_accuracy_by_block.jpg"), width=9, height=6)

Word Recall by Block

plot_grid(
  training_recall_by_block_exp1,
  training_recall_by_block_exp2,
  training_recall_by_block_exp3,
  training_recall_by_block_exp4,
  ncol=2,
  labels=c("A","B","C","D"))

ggsave(here::here("plots","training_recall_by_block.jpg"), width=9, height=6)